Skip to content

Commit c26ce8c

Browse files
committed
Implement TaskSeq.forall and forallAsync; add Task/ValueTask boolean operator overloads
1 parent 2fc7d94 commit c26ce8c

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

src/FSharp.Control.TaskSeq/TaskSeq.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,9 @@ type TaskSeq private () =
360360
static member except itemsToExclude source = Internal.except itemsToExclude source
361361
static member exceptOfSeq itemsToExclude source = Internal.exceptOfSeq itemsToExclude source
362362

363+
static member forall predicate source = Internal.forall (Predicate predicate) source
364+
static member forallAsync predicate source = Internal.forall (PredicateAsync predicate) source
365+
363366
static member exists predicate source =
364367
Internal.tryFind (Predicate predicate) source
365368
|> Task.map Option.isSome

src/FSharp.Control.TaskSeq/TaskSeqInternal.fs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -690,18 +690,54 @@ module internal TaskSeqInternal =
690690

691691
taskSeq {
692692
match predicate with
693-
| Predicate predicate ->
693+
| Predicate syncPredicate ->
694694
for item in source do
695-
if predicate item then
695+
if syncPredicate item then
696696
yield item
697697

698-
| PredicateAsync predicate ->
698+
| PredicateAsync asyncPredicate ->
699699
for item in source do
700-
match! predicate item with
700+
match! asyncPredicate item with
701701
| true -> yield item
702702
| false -> ()
703703
}
704704

705+
let forall predicate (source: TaskSeq<_>) =
706+
checkNonNull (nameof source) source
707+
708+
match predicate with
709+
| Predicate syncPredicate -> task {
710+
use e = source.GetAsyncEnumerator CancellationToken.None
711+
let mutable state = true
712+
let! cont = e.MoveNextAsync()
713+
let mutable hasMore = cont
714+
715+
while state && hasMore do
716+
state <- syncPredicate e.Current
717+
718+
if state then
719+
let! cont = e.MoveNextAsync()
720+
hasMore <- cont
721+
722+
return state
723+
}
724+
725+
| PredicateAsync asyncPredicate -> task {
726+
use e = source.GetAsyncEnumerator CancellationToken.None
727+
let mutable state = true
728+
let! cont = e.MoveNextAsync()
729+
let mutable hasMore = cont
730+
731+
while state && hasMore do
732+
let! pred = asyncPredicate e.Current
733+
state <- pred
734+
735+
if state then
736+
let! cont = e.MoveNextAsync()
737+
hasMore <- cont
738+
739+
return state
740+
}
705741

706742
let skipOrTake skipOrTake count (source: TaskSeq<_>) =
707743
checkNonNull (nameof source) source

src/FSharp.Control.TaskSeq/Utils.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ module ValueTask =
4242

4343

4444
module Task =
45+
let False = Task.FromResult false
46+
let True = Task.FromResult true
4547
let inline fromResult (value: 'U) : Task<'U> = Task.FromResult value
4648
let inline ofAsync (async: Async<'T>) = task { return! async }
4749
let inline ofTask (task': Task) = task { do! task' }

src/FSharp.Control.TaskSeq/Utils.fsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ module ValueTask =
4949
val inline ignore: vtask: ValueTask<'T> -> ValueTask
5050

5151
module Task =
52+
/// A successfully completed Task of boolean that has the value false.
53+
val False: Task<bool>
54+
55+
/// A successfully completed Task of boolean that has the value true.
56+
val True: Task<bool>
5257

5358
/// Convert an Async<'T> into a Task<'T>
5459
val inline ofAsync: async: Async<'T> -> Task<'T>

0 commit comments

Comments
 (0)