Using the FsToolkit.ErrorHandling library, let's take an example:
let doStuff =
result {
let! x = doSomething "hello"
let! y = doAnotherthing "world"
let z = combineTwo x y
return z
}
now, I have an async version of combinedTwo called combinedTwoAsync:
let doStuff =
result {
let! x = doSomething "hello"
let! y = doAnotherthing "world"
let z = combineTwoAsync x y |> Async.AwaitTask |> Async.RunSynchronously
return z
}
but I saw that they have an asyncResult expression which returns an Async<Result<'a, 'b>> type
however, I can't do something like:
let doStuff =
asyncResult {
let! x = doSomething "hello"
let! y = doAnotherthing "world"
let! z = combineTwoAsync x y
return z
}
since doSomethingAsync is just an async function that doesn't return a Result object
I guess this was planned with the idea that all async functions would return an Async<Result<>> type, but I'm trying to figure out how to use async calls (which are to external libs) within a result computation expression to return an Async<Result<>>..
hopefully this makes some sense :)
1 Answer 1
In general, for functors (of which async is one), one could use map to apply some sort of transformation to the functor's value, such as wrapping it in a Result.Ok, for example:
// xAsyncResult : Async<Result<_,_>>
let xAsyncResult = doSomething "hello" |> Async.map Result.Ok
Surprisingly, Async.map is a not a thing. There's even an issue about it.
But no matter: it's easy enough to implement:
module Async =
map f a = async {
let! x = a
return f a
}
And then:
let doStuff =
asyncResult {
let! x = doSomething "hello" |> Async.map Result.Ok
let! y = doAnotherthing "world" |> Async.map Result.Ok
let! z = combineTwoAsync x y
return z
}