Skip to content

Commit 9ee69d0

Browse files
Jimmy ByrdTheAngryByrd
authored andcommitted
Fixed #86
Allows for binding the outer async for complex workflows
1 parent fd5365c commit 9ee69d0

File tree

6 files changed

+89
-2
lines changed

6 files changed

+89
-2
lines changed

src/FsToolkit.ErrorHandling.JobResult/JobResultCE.fs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,12 @@ module JobResultCEExtensions =
151151
/// Method lets us transform data types into our internal representation.
152152
/// </summary>
153153
member inline _.Source(t : Task) : Job<Result<_,_>> = t |> Job.awaitUnitTask |> Job.map Ok
154-
154+
155+
member inline __.Bind(asyncComputation: Async<_>, binder: 'T -> Job<Result<'U, 'TError>>) : Job<Result<'U, 'TError>> =
156+
__.Bind(asyncComputation |> Async.map Ok |> Job.fromAsync, binder)
157+
158+
member inline __.Bind(asyncComputation: Task<_>, binder: 'T -> Job<Result<'U, 'TError>>) : Job<Result<'U, 'TError>> =
159+
__.Bind(asyncComputation |> Task.map Ok |> Job.awaitTask, binder)
160+
161+
member inline __.Bind(asyncComputation: Job<_>, binder: 'T -> Job<Result<'U, 'TError>>) : Job<Result<'U, 'TError>> =
162+
__.Bind(asyncComputation |> Job.map Ok, binder)

src/FsToolkit.ErrorHandling.TaskResult/TaskResultCE.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ module TaskResultCE =
6868
| Error x -> ret <| Error x
6969
bindTaskConfigureFalse taskResult binder'
7070

71+
72+
73+
7174
member __.Delay
7275
(generator: unit -> Step<Result<'T, 'TError>>) =
7376
task.Delay(generator)
@@ -161,3 +164,9 @@ module TaskResultCEExtensions =
161164
/// Method lets us transform data types into our internal representation.
162165
/// </summary>
163166
member inline _.Source(t : Task) : Task<Result<_,_>> = task { return! t } |> Task.map Ok
167+
168+
member inline __.Bind(asyncComputation: Async<_>, binder: 'T -> Step<Result<'U, 'TError>>) : Step<Result<'U, 'TError>> =
169+
__.Bind(asyncComputation |> Async.map Ok |> Async.StartAsTask, binder)
170+
171+
member inline __.Bind(asyncComputation: Task<_>, binder: 'T -> Step<Result<'U, 'TError>>) : Step<Result<'U, 'TError>> =
172+
__.Bind(asyncComputation |> Task.map Ok, binder)

src/FsToolkit.ErrorHandling/AsyncResultCE.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ module AsyncResultCEExtensions =
121121
/// </summary>
122122
member inline __.Source(asyncComputation : Async<_>) : Async<Result<_,_>> = asyncComputation |> Async.map Ok
123123

124+
125+
member inline __.Bind(asyncComputation: Async<_>, binder: 'T -> Async<Result<'U, 'TError>>) : Async<Result<'U, 'TError>> =
126+
__.Bind(asyncComputation |> Async.map Ok, binder)
127+
124128
#if !FABLE_COMPILER
125129
/// <summary>
126130
/// Method lets us transform data types into our internal representation.
@@ -131,4 +135,8 @@ module AsyncResultCEExtensions =
131135
/// Method lets us transform data types into our internal representation.
132136
/// </summary>
133137
member inline _.Source(task : Task) : Async<Result<_,_>> =task |> Async.AwaitTask |> Async.map Ok
138+
139+
140+
member inline __.Bind(asyncComputation: Task<_>, binder: 'T -> Async<Result<'U, 'TError>>) : Async<Result<'U, 'TError>> =
141+
__.Bind(asyncComputation |> Async.AwaitTask |> Async.map Ok, binder)
134142
#endif

tests/FsToolkit.ErrorHandling.JobResult.Tests/JobResultCE.fs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,32 @@ let ``JobResultCE bind Tests`` =
146146

147147
Expect.equal actual (Result.Ok ()) "Should be ok"
148148
}
149+
testCaseJob "Let! outer Async wrapper" <| job {
150+
let innerData = "Foo"
151+
let! f = jobResult {
152+
let! (r : Result<_,_>) = AsyncResult.retn innerData
153+
Expect.equal r (Ok innerData) "Should be ok"
154+
}
155+
()
156+
}
157+
158+
testCaseJob "Let! outer Task wrapper" <| job {
159+
let innerData = "Foo"
160+
let! f = jobResult {
161+
let! (r : Result<_,_>) = Task.FromResult(Ok innerData)
162+
Expect.equal r (Ok innerData) "Should be ok"
163+
}
164+
()
165+
}
166+
167+
testCaseJob "Let! outer Job wrapper" <| job {
168+
let innerData = "Foo"
169+
let! f = jobResult {
170+
let! (r : Result<_,_>) = Job.result (Ok innerData)
171+
Expect.equal r (Ok innerData) "Should be ok"
172+
}
173+
()
174+
}
149175
]
150176

151177

tests/FsToolkit.ErrorHandling.TaskResult.Tests/TaskResultCE.fs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,23 @@ let ``TaskResultCE bind Tests`` =
142142

143143
Expect.equal actual (Result.Ok ()) "Should be ok"
144144
}
145+
testCaseTask "Let! outer Async wrapper" <| task {
146+
let innerData = "Foo"
147+
let! f = taskResult {
148+
let! (r : Result<_,_>) = AsyncResult.retn innerData
149+
Expect.equal r (Ok innerData) "Should be ok"
150+
}
151+
()
152+
}
153+
154+
testCaseTask "Let! outer Task wrapper" <| task {
155+
let innerData = "Foo"
156+
let! f = taskResult {
157+
let! (r : Result<_,_>) = Task.FromResult(Ok innerData)
158+
Expect.equal r (Ok innerData) "Should be ok"
159+
}
160+
()
161+
}
145162
]
146163

147164

tests/FsToolkit.ErrorHandling.Tests/AsyncResultCE.fs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ let ``AsyncResultCE bind Tests`` =
9090
return data
9191
}
9292
Expect.equal actual (data) "Should be ok"
93-
9493
}
94+
9595
testCaseAsync "Bind Ok Choice" <| async {
9696
let innerData = "Foo"
9797
let data = Choice1Of2 innerData
@@ -113,6 +113,7 @@ let ``AsyncResultCE bind Tests`` =
113113
Expect.equal actual (data) "Should be ok"
114114
}
115115

116+
116117
testCaseAsync "Bind Async" <| async {
117118
let innerData = "Foo"
118119
let d = Async.singleton innerData
@@ -124,6 +125,15 @@ let ``AsyncResultCE bind Tests`` =
124125
Expect.equal actual (Result.Ok innerData) "Should be ok"
125126
}
126127

128+
testCaseAsync "Let! outer Async wrapper" <| async {
129+
let innerData = "Foo"
130+
let! f = asyncResult {
131+
let! (r : Result<_,_>) = AsyncResult.retn innerData
132+
Expect.equal r (Ok innerData) "Should be ok"
133+
}
134+
()
135+
}
136+
127137

128138
#if !FABLE_COMPILER
129139
testCaseAsync "Bind Ok TaskResult" <| async {
@@ -153,6 +163,15 @@ let ``AsyncResultCE bind Tests`` =
153163

154164
Expect.equal actual (Result.Ok ()) "Should be ok"
155165
}
166+
167+
testCaseAsync "Let! outer Task wrapper" <| async {
168+
let innerData = "Foo"
169+
let! f = asyncResult {
170+
let! (r : Result<_,_>) = Task.FromResult(Ok innerData)
171+
Expect.equal r (Ok innerData) "Should be ok"
172+
}
173+
()
174+
}
156175
#endif
157176
]
158177

0 commit comments

Comments
 (0)