Skip to content

Commit

Permalink
Add TaskSeq.tail and tryTail functions (todo: tests)
Browse files Browse the repository at this point in the history
  • Loading branch information
abelbraaksma committed Nov 6, 2022
1 parent 4190550 commit f326bc7
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
7 changes: 7 additions & 0 deletions src/FSharp.Control.TaskSeq/TaskSeq.fs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@ module TaskSeq =
| None -> return Internal.raiseEmptySeq ()
}

let tryTail source = Internal.tryTail source

let tail source = task {
match! Internal.tryTail source with
| Some result -> return result
| None -> return Internal.raiseEmptySeq ()
}
let tryItem index source = Internal.tryItem index source

let item index source = task {
Expand Down
17 changes: 13 additions & 4 deletions src/FSharp.Control.TaskSeq/TaskSeq.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -232,21 +232,30 @@ module TaskSeq =
val collectSeqAsync: binder: ('T -> #Task<'SeqU>) -> source: taskSeq<'T> -> taskSeq<'U> when 'SeqU :> seq<'U>

/// <summary>
/// Returns the first element of the <see cref="taskSeq" />, or <see cref="None" /> if the sequence is empty.
/// Returns the first element of the task sequence from <paramref name="source" />, or <see cref="None" /> if the sequence is empty.
/// </summary>
/// <exception cref="ArgumentException">Thrown when the sequence is empty.</exception>
val tryHead: source: taskSeq<'T> -> Task<'T option>

/// <summary>
/// Returns the first element of the <see cref="taskSeq" />.
/// Returns the first elementof the task sequence from <paramref name="source" />
/// </summary>
/// <exception cref="ArgumentException">Thrown when the sequence is empty.</exception>
val head: source: taskSeq<'T> -> Task<'T>

/// <summary>
/// Returns the last element of the <see cref="taskSeq" />, or <see cref="None" /> if the sequence is empty.
/// Returns the whole task sequence from <paramref name="source" />, minus its first element, or <see cref="None" /> if the sequence is empty.
/// </summary>
val tryTail: source: taskSeq<'T> -> Task<taskSeq<'T> option>

/// <summary>
/// Returns the whole task sequence from <paramref name="source" />, minus its first element.
/// </summary>
/// <exception cref="ArgumentException">Thrown when the sequence is empty.</exception>
val tail: source: taskSeq<'T> -> Task<taskSeq<'T>>

/// <summary>
/// Returns the last element of the task sequence from <paramref name="source" />, or <see cref="None" /> if the sequence is empty.
/// </summary>
val tryLast: source: taskSeq<'T> -> Task<'T option>

/// <summary>
Expand Down
27 changes: 23 additions & 4 deletions src/FSharp.Control.TaskSeq/TaskSeqInternal.fs
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,30 @@ module internal TaskSeqInternal =

let tryHead (source: taskSeq<_>) = task {
use e = source.GetAsyncEnumerator(CancellationToken())
let mutable go = true
let! step = e.MoveNextAsync()
go <- step

if go then return Some e.Current else return None
match! e.MoveNextAsync() with
| true -> return Some e.Current
| false -> return None
}

let tryTail (source: taskSeq<_>) = task {
use e = source.GetAsyncEnumerator(CancellationToken())

match! e.MoveNextAsync() with
| false -> return None
| true ->
return
taskSeq {
let mutable go = true
let! step = e.MoveNextAsync()
go <- step

while go do
yield e.Current
let! step = e.MoveNextAsync()
go <- step
}
|> Some
}

let tryItem index (source: taskSeq<_>) = task {
Expand Down

0 comments on commit f326bc7

Please sign in to comment.