File tree Expand file tree Collapse file tree 2 files changed +84
-0
lines changed
src/FsToolkit.ErrorHandling
tests/FsToolkit.ErrorHandling.Tests Expand file tree Collapse file tree 2 files changed +84
-0
lines changed Original file line number Diff line number Diff line change @@ -321,6 +321,28 @@ module Option =
321321
322322 opt
323323
324+ /// Converts a Option<Async<_>> to an Async<Option<_>>
325+ let inline sequenceAsync ( optAsync : Option < Async < 'T >>) : Async < Option < 'T >> =
326+ async {
327+ match optAsync with
328+ | Some asnc ->
329+ let! x = asnc
330+ return Some x
331+ | None -> return None
332+ }
333+
334+ /// <summary>
335+ /// Maps an Async function over an Option, returning an Async Option.
336+ /// </summary>
337+ /// <param name="f">The function to map over the Option.</param>
338+ /// <param name="opt">The Option to map over.</param>
339+ /// <returns>An Async Option with the mapped value.</returns>
340+ let inline traverseAsync
341+ ( [<InlineIfLambda>] f : 'T -> Async < 'T >)
342+ ( opt : Option < 'T >)
343+ : Async < Option < 'T >> =
344+ sequenceAsync (( map f) opt)
345+
324346 /// <summary>
325347 /// Creates an option from a boolean value and a value of type 'a.
326348 /// If the boolean value is true, returns <c>Some</c> value.
Original file line number Diff line number Diff line change @@ -184,6 +184,66 @@ let teeIfTests =
184184 Expect.equal foo " foo" " "
185185 ]
186186
187+ let sequenceAsyncTests =
188+ testList " Option.sequenceAsync Tests" [
189+ testCaseAsync " sequenceAsync returns the async value if Some"
190+ <| async {
191+ let optAsync =
192+ async { return " foo" }
193+ |> Some
194+
195+ let! value =
196+ optAsync
197+ |> Option.sequenceAsync
198+
199+ Expect.equal value ( Some " foo" ) " "
200+ }
201+
202+ testCaseAsync " sequenceAsync returns None if None"
203+ <| async {
204+ let optAsync = None
205+
206+ let! value =
207+ optAsync
208+ |> Option.sequenceAsync
209+
210+ Expect.equal value None " "
211+ }
212+ ]
213+
214+ let traverseAsyncTests =
215+ testList " Option.traverseAsync Tests" [
216+ testCaseAsync " traverseAsync returns the async value if Some"
217+ <| async {
218+ let optAsync = Some " foo"
219+
220+ let optFunc =
221+ id
222+ >> Async.singleton
223+
224+ let! value =
225+ ( optFunc, optAsync)
226+ ||> Option.traverseAsync
227+
228+ Expect.equal value ( Some " foo" ) " "
229+ }
230+
231+ testCaseAsync " traverseAsync returns None if None"
232+ <| async {
233+ let optAsync = None
234+
235+ let optFunc =
236+ id
237+ >> Async.singleton
238+
239+ let! value =
240+ ( optFunc, optAsync)
241+ ||> Option.traverseAsync
242+
243+ Expect.equal value None " "
244+ }
245+ ]
246+
187247let traverseResultTests =
188248 testList " Option.traverseResult Tests" [
189249 testCase " traverseResult with Some of valid data"
@@ -366,6 +426,8 @@ let optionOperatorsTests =
366426
367427let allTests =
368428 testList " Option Tests" [
429+ sequenceAsyncTests
430+ traverseAsyncTests
369431 traverseResultTests
370432 tryParseTests
371433 tryGetValueTests
You can’t perform that action at this time.
0 commit comments