F# 是否有一个 Async.Sequential 来匹配 Async.Parallel?



F# 具有具有类型签名seq<Async<'a>> -> Async<'a list>Async.Parallel,它将采用异步类型的序列,准备它们并行运行,并输出单个异步。

我想知道是否有一个类似的Async.Sequential具有相同类型的签名,但一个接一个地按顺序运行每个项目?我觉得我一定错过了什么明显的东西?

我想做如下事情:

async {
let! results =
myItems
|> List.map myAsynchronousOperation
|> Async.Sequential
... do something with results
}

我不认为有一个内置的,但编写自己的应该很简单:

let sequential s = async {
let results = ResizeArray()
for a in s do
let! result = a
results.Add(result)
return List.ofSeq results
}

按顺序评估seq<Async<'a>>中的项目并返回列表实际上只是在简单地将其cons到列表中之前要评估async的序列上的一个foldBack。 虽然 kvb 的解决方案当然有效,但您也可以使用如下Seq.foldBack

module Async =
let sequential s = 
Seq.foldBack (fun cur acc -> async.Bind(cur, fun head -> 
async.Bind(acc, fun tail -> async.Return(head :: tail)))) s (async.Return [])

随着 F# 4.7 和 FSharp.Core 4.7 的发布,Async.Sequential现在可以"开箱即用"使用。

公告:https://devblogs.microsoft.com/dotnet/announcing-f-4-7/

来源: https://github.com/dotnet/fsharp/blob/897afd3dad3bfe58a0495713e99a8094098c18c5/src/fsharp/FSharp.Core/async.fs#L1282

如果有人愿意使用 AsyncSeq 库,那么以下内容可以满足给定示例中的需求:

async {
let! results =
myItems
|> AsyncSeq.ofSeq
|> AsyncSeq.mapAsync myAsynchronousOperation
|> AsyncSeq.toListAsync
... do something with results
}

不过,如果您还没有将 AsyncSeq 用于其他事情,则可能矫枉过正。

最新更新