diff --git a/src/FSharp.Control.TaskSeq/TaskSeq.fs b/src/FSharp.Control.TaskSeq/TaskSeq.fs index 7775e2e..710dadd 100644 --- a/src/FSharp.Control.TaskSeq/TaskSeq.fs +++ b/src/FSharp.Control.TaskSeq/TaskSeq.fs @@ -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 diff --git a/src/FSharp.Control.TaskSeq/TaskSeqInternal.fs b/src/FSharp.Control.TaskSeq/TaskSeqInternal.fs index 5827637..d7773ce 100644 --- a/src/FSharp.Control.TaskSeq/TaskSeqInternal.fs +++ b/src/FSharp.Control.TaskSeq/TaskSeqInternal.fs @@ -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