Skip to content

Commit 547874e

Browse files
committed
Add more Sequential overloads
1 parent 726b20b commit 547874e

File tree

1 file changed

+62
-1
lines changed

1 file changed

+62
-1
lines changed

src/FSharpPlus/Extensions/Extensions.fs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,26 @@ module Extensions =
6060
tcs.SetResult results
6161
t.ContinueWith (continuation, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default) |> ignore)
6262
tcs.Task
63+
64+
65+
/// Creates a task Result from a Result where the Ok case is a task.
66+
static member Sequential (t: Result<Task<'T>, 'Error>) : Task<Result<'T, 'Error>> = Result.either (Task.map Ok) (Task.result << Error) t
67+
68+
/// Creates a task Result from a Result where the Ok case is a task.
69+
static member Sequential (t: Choice<Task<'T>, 'Error>) : Task<Choice<'T, 'Error>> = Choice.either (Task.map Choice1Of2) (Task.result << Choice2Of2) t
70+
71+
#endif
72+
73+
#if !NET45 && !NETSTANDARD2_0 && !FABLE_COMPILER
74+
75+
type ValueTask<'t> with
76+
77+
/// Creates a task Result from a Result where the Ok case is a task.
78+
static member Sequential (t: Result<ValueTask<'T>, 'Error>) : ValueTask<Result<'T, 'Error>> = Result.either (ValueTask.map Ok) (ValueTask.result << Error) t
79+
80+
/// Creates a task Result from a Result where the Ok case is a task.
81+
static member Sequential (t: Choice<ValueTask<'T>, 'Error>) : ValueTask<Choice<'T, 'Error>> = Choice.either (ValueTask.map Choice1Of2) (ValueTask.result << Choice2Of2) t
82+
6383
#endif
6484

6585
type Async<'t> with
@@ -171,8 +191,8 @@ module Extensions =
171191
elif task.IsCanceled then cc (TaskCanceledException ())
172192
else sc ())
173193
|> ignore)
174-
175194

195+
176196
/// Combine all asyncs in one, chaining them in sequence order.
177197
/// Similar to Async.Sequential but the returned Async contains a sequence, which is lazily evaluated.
178198
static member SequentialLazy (t: seq<Async<'T>>) : Async<seq<_>> = async {
@@ -393,3 +413,44 @@ module Extensions =
393413
match error with
394414
| ValueNone -> Ok (Array.toSeq res)
395415
| ValueSome e -> Error e
416+
417+
/// Returns the first Error if it contains an Error element, otherwise a list of all elements.
418+
static member Sequential (t: list<Result<'T, 'Error>>) =
419+
#if FABLE_COMPILER
420+
let mutable error = ValueNone
421+
let res = Seq.toList (seq {
422+
use e = (t :> seq<_>).GetEnumerator ()
423+
while e.MoveNext () && error.IsNone do
424+
match e.Current with
425+
| Ok v -> yield v
426+
| Error e -> error <- ValueSome e })
427+
428+
match error with
429+
| ValueNone -> Ok res
430+
| ValueSome e -> Error e
431+
#else
432+
let mutable accumulator = ListCollector<'T> ()
433+
let mutable error = ValueNone
434+
use e = (t :> seq<_>).GetEnumerator ()
435+
while e.MoveNext () && error.IsNone do
436+
match e.Current with
437+
| Ok v -> accumulator.Add v
438+
| Error x -> error <- ValueSome x
439+
match error with
440+
| ValueNone -> Ok (accumulator.Close ())
441+
| ValueSome x -> Error x
442+
#endif
443+
444+
/// Returns the Error if it contains an Error element, otherwise the option inside an Ok.
445+
static member Sequential (t: option<Result<'T, 'Error>>) =
446+
match t with
447+
| Some (Ok x) -> Ok (Some x)
448+
| None -> Ok None
449+
| Some (Error x) -> Error x
450+
451+
/// Returns the Error if it contains an Error element, otherwise the voption inside an Ok.
452+
static member Sequential (t: voption<Result<'T, 'Error>>) =
453+
match t with
454+
| ValueSome (Ok x) -> Ok (ValueSome x)
455+
| ValueNone -> Ok ValueNone
456+
| ValueSome (Error x) -> Error x

0 commit comments

Comments
 (0)