我试图找出以下F#表达式的有效语法。假设我有一个F#异步计算:
let asyncComp n = async { return n }
有签名'a -> Async<'a>
。现在,我定义一个序列:
let seqOfAsyncComps =
seq {
yield asyncComp 1
yield asyncComp 2
yield asyncComp 3
}
现在我有一个项目seq<Async<int>>
。如果我想从元素异步映射seq<Async<int>>
到seq<Async<int>>
。这行不通:
let seqOfAsyncSquares =
seqOfAsyncComps |> Seq.map (fun x -> x * x) // ERROR!!!
当然,x
是Async<int>
,我必须先提取一个int
,所以我可以改为执行以下操作:
let seqOfAsyncSquares =
seqOfAsyncComps |> Seq.map (fun x -> async {
let! y = x
return y * y }) // OK
这可以正常工作,但是语法很笨拙。它带走了F#紧凑,如果我想链几种seq
处理我必须做同样的伎俩在每一个map
,filter
或iter
。
我怀疑可能会有更有效的语法来处理由异步计算组成的序列。
您可以使用Async.map
(我现在才从Tomas Petricek偷来的):
module Async =
let map f workflow = async {
let! res = workflow
return f res }
let seqOfAsyncSquares' =
seqOfAsyncComps |> Seq.map (Async.map (fun x -> x * x))
如果对其进行评估,您会发现它似乎产生了预期的结果:
> seqOfAsyncSquares' |> Async.Parallel |> Async.RunSynchronously;;
val it : int [] = [|1; 4; 9|]
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句