【发布时间】:2014-08-08 15:44:58
【问题描述】:
最近在编写一些适用于许多嵌套异步工作流程的代码时,我发现了一种新出现的模式,让我觉得很奇怪。一个简单的例子:
let flip f x y = f y x
let slowInc x = async {
do! Async.Sleep 500
printfn "Here you go, %d" x
}
let verboseFun inp = async {
match List.tryFind (flip (>) 3) inp with
| Some x -> do! slowInc x
| _ -> ()
}
verboseFun [1..5] |> Async.RunSynchronously
'verboseFun' 对我来说似乎很冗长,但我想不出一种方法来组合 Option 和 Async monad,这样就可以在没有模式匹配的情况下重写它。我在想类似的东西
let terseFun inp = async {
inp
|> List.tryFind (flip (>) 3)
|> Option.iterAsync slowInc
}
在我看来,我很可能只是不知道有哪些构建块可以实现这一目标。
编辑:托马斯回答后的额外说明。
如果一切都是同步的,我试图适应对我来说微不足道的事情,例如,
let terseFun inp =
inp
|> List.tryFind (flip (>) 3)
|> Option.iter someSideEffectFunciton
成为嵌套异步工作流程的一部分。最初我在想“只是随便做一个!在那里”所以想出了
let terseFun inp = async {
inp
|> List.tryFind (flip (>) 3)
|> Option.iter (fun x -> async { do! someSideEffectFunciton x })
|> ignore
}
但我立刻觉得它不对劲,因为 VS 开始要求忽略。 希望这有助于澄清。
【问题讨论】:
-
更通用的解决方案是使用 Monad Transformers,尽管在 F# 中它们并不简单,您可以查看 github.com/gmpl/FsControl/blob/master/FsControl.Core/Samples/… 中的 FsControl
标签: asynchronous f# monads monad-transformers async-workflow