Skip to content

Commit

Permalink
Implement TaskSeq.forall and forallAsync
Browse files Browse the repository at this point in the history
  • Loading branch information
abelbraaksma committed Mar 16, 2024
1 parent 3d2c998 commit 1deb2f8
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/FSharp.Control.TaskSeq/TaskSeq.fs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,9 @@ type TaskSeq private () =
static member except itemsToExclude source = Internal.except itemsToExclude source
static member exceptOfSeq itemsToExclude source = Internal.exceptOfSeq itemsToExclude source

static member forall predicate source = Internal.forall (Predicate predicate) source
static member forallAsync predicate source = Internal.forall (PredicateAsync predicate) source

static member exists predicate source =
Internal.tryFind (Predicate predicate) source
|> Task.map Option.isSome
Expand Down
44 changes: 40 additions & 4 deletions src/FSharp.Control.TaskSeq/TaskSeqInternal.fs
Original file line number Diff line number Diff line change
Expand Up @@ -690,18 +690,54 @@ module internal TaskSeqInternal =

taskSeq {
match predicate with
| Predicate predicate ->
| Predicate syncPredicate ->
for item in source do
if predicate item then
if syncPredicate item then
yield item

| PredicateAsync predicate ->
| PredicateAsync asyncPredicate ->
for item in source do
match! predicate item with
match! asyncPredicate item with
| true -> yield item
| false -> ()
}

let forall predicate (source: TaskSeq<_>) =
checkNonNull (nameof source) source

match predicate with
| Predicate syncPredicate -> task {
use e = source.GetAsyncEnumerator CancellationToken.None
let mutable state = true
let! cont = e.MoveNextAsync()
let mutable hasMore = cont

while state && hasMore do
state <- syncPredicate e.Current

if state then
let! cont = e.MoveNextAsync()
hasMore <- cont

return state
}

| PredicateAsync asyncPredicate -> task {
use e = source.GetAsyncEnumerator CancellationToken.None
let mutable state = true
let! cont = e.MoveNextAsync()
let mutable hasMore = cont

while state && hasMore do
let! pred = asyncPredicate e.Current
state <- pred

if state then
let! cont = e.MoveNextAsync()
hasMore <- cont

return state
}

let skipOrTake skipOrTake count (source: TaskSeq<_>) =
checkNonNull (nameof source) source
Expand Down

0 comments on commit 1deb2f8

Please sign in to comment.