如何在 F# 中使用 Async 和 AsyncResult

how to use Async with AsyncResult in F#

使用FsToolkit.ErrorHandling库,举个例子:

let doStuff =
    result {
        let! x = doSomething "hello"
        let! y = doAnotherthing "world"
        let  z = combineTwo x y
        return z
    }

现在,我有一个名为 combinedTwoAsync 的 combinedTwo 的异步版本:

let doStuff =
    result {
        let! x = doSomething "hello"
        let! y = doAnotherthing "world"
        let  z = combineTwoAsync x y |> Async.AwaitTask |> Async.RunSynchronously
        return z
    }

但我看到他们有一个 asyncResult 表达式,return是一个 Async> 类型

但是,我不能做类似的事情:

let doStuff =
    asyncResult {
        let! x = doSomething "hello"
        let! y = doAnotherthing "world"
        let! z = combineTwoAsync x y
        return z
    }

因为 doSomethingAsync 只是一个异步函数,没有 return 结果对象

我想这是计划好的,所有异步函数都将 return 为 Async> 类型,但我正在尝试弄清楚如何使用异步调用(对外部调用libs) 在结果计算表达式中 return 一个 Async>..

希望这是有道理的:)

一般来说,对于函子(async 是其中之一),可以使用 map 对函子的值进行某种转换,例如将其包装在 Result.Ok,例如:

// xAsyncResult : Async<Result<_,_>>
let xAsyncResult = doSomething "hello" |> Async.map Result.Ok

令人惊讶的是,Async.map 不是一回事。甚至还有 an issue about it.

但没关系:实施起来很容易:

module Async =
  map f a = async {
    let! x = a
    return f a
  }

然后:

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
    }