Skip to content

Commit 8a69692

Browse files
gustywallymathieu
authored andcommitted
Add bindTask and bindInto to Result (#659)
1 parent 3162ab6 commit 8a69692

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

src/FSharpPlus/Data/Error.fs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,38 @@ open FSharpPlus.Control
1111
/// Additional operations on Result
1212
[<RequireQualifiedAccess>]
1313
module Result =
14+
15+
open System.Threading.Tasks
16+
1417
let inline traverse f = function Ok x -> Map.Invoke Ok (f x) | Error x -> result (Error x)
18+
19+
/// <summary>
20+
/// Binds a result into a generic monad (e.g., Option, List, Async, etc.)
21+
/// </summary>
22+
/// <param name="binder">The function to bind if the result is Ok.</param>
23+
/// <param name="source">The result to bind from.</param>
24+
/// <returns>The resulting monad containing a result.</returns>
25+
#if !NET45
26+
let inline bindInto ([<InlineIfLambda>]binder: 'T -> '``Monad<Result<'U, 'Error>>``) (source: Result<'T, 'Error>) : '``Monad<Result<'U, 'Error>>`` =
27+
#else
28+
let inline bindInto (binder: 'T -> '``Monad<Result<'U, 'Error>>``) (source: Result<'T, 'Error>) : '``Monad<Result<'U, 'Error>>`` =
29+
#endif
30+
source |> Result.either binder (Error >> result)
31+
32+
/// <summary>
33+
/// Binds a result into a Task.
34+
/// </summary>
35+
/// <param name="binder">The function to bind if the result is Ok.</param>
36+
/// <param name="source">The result to bind from.</param>
37+
/// <returns>The resulting Task containing a result.</returns>
38+
/// <remarks>This is a specialized version of bindInto for Task monad.</remarks>
39+
#if !NET45
40+
let inline bindTask ([<InlineIfLambda>]binder: 'T -> Task<Result<'U, 'Error>>) (source: Result<'T, 'Error>) : Task<Result<'U, 'Error>> =
41+
#else
42+
let inline bindTask (binder: 'T -> Task<Result<'U, 'Error>>) (source: Result<'T, 'Error>) : Task<Result<'U, 'Error>> =
43+
#endif
44+
source |> Result.either binder (Error >> Task.result)
45+
1546
#endif
1647

1748
/// Result<'TSuccess,'TFailure> specialized in 'TFailure = Exception
@@ -49,7 +80,7 @@ module ResultT =
4980
/// Transform a Result<'T,'Error> to a ResultT<'Monad<Result<'T,'Error>>>
5081
let inline hoist (x: Result<'T,'TError>) = ResultT (result x) : ResultT<'``Monad<Result<'T,'TError>>``>
5182

52-
let inline bind (f: 'T->ResultT<'``Monad<Result<'U,'E>>``>) (ResultT m: ResultT<'``Monad<Result<'T,'E>>``>) = (ResultT (m >>= (fun a -> match a with Error l -> result (Error l) | Ok r -> run (f r))))
83+
let inline bind (f: 'T->ResultT<'``Monad<Result<'U,'E>>``>) (ResultT m: ResultT<'``Monad<Result<'T,'E>>``>) = m >>= Result.bindInto (f >> run) |> ResultT
5384

5485
let inline apply (ResultT f:ResultT<'``Monad<Result<('T -> 'U),'E>>``>) (ResultT x: ResultT<'``Monad<Result<'T,'E>>``>) = ResultT (map Result.apply f <*> x) : ResultT<'``Monad<Result<'U,'E>>``>
5586
let inline map (f: 'T->'U) (ResultT m: ResultT<'``Monad<Result<'T,'E>>``>) = ResultT (map (Result.map f) m) : ResultT<'``Monad<Result<('T -> 'U),'E>>``>

0 commit comments

Comments
 (0)