在调用F#异步工作流时,我可以避免定义临时标签吗?

Wal*_*lly 2 f# async-workflow

假设我有一个异步数据源:

let getData() = async { return [ 3.14; 2.72 ] }
Run Code Online (Sandbox Code Playgroud)

我可以使用let!和临时标签来调用它:

let showData1() = async {
    let! data = getData()
    data
    |> Seq.iter (printfn "%A")
}
Run Code Online (Sandbox Code Playgroud)

或者,我可以称之为(效率低下!)使用Async.RunSynchronously和管道,没有临时标签:

let showData2() = async {
    getData()
    |> Async.RunSynchronously
    |> Seq.iter (printfn "%A")
}
Run Code Online (Sandbox Code Playgroud)

我喜欢语法,showData2但知道调用Async.RunSynchronously绑定了调用线程.

是否在某处定义了语法,运算符或函数,允许我将其Async<'T>输入到接受的函数中'T

Lee*_*Lee 5

这听起来像你想要mapAsync:

let mapAsync f a = async { 
    let! v = a
    return (f v)
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

let m: Async<unit> = getData() |> mapAsync (Seq.iter (printfn "%A"))
Run Code Online (Sandbox Code Playgroud)

  • 我把它标记为答案.看起来很完美.但是,既然我已经尝试在我的"真实"项目中使用它几天了,我发现语法仍然很尴尬.`mapAsync`返回一个`Async <'T>`,不像`Async.RunSynchronously`,它返回'T. 我开始认为我想要的东西需要像`let!`和`do!`这样的语言功能,但对于前进管道.思考? (2认同)