我正在尝试使用自由Monad模式构建消息处理管道,我的代码如下:
module PipeMonad =
type PipeInstruction<'msgIn, 'msgOut, 'a> =
| HandleAsync of 'msgIn * (Async<'msgOut> -> 'a)
| SendOutAsync of 'msgOut * (Async -> 'a)
let private mapInstruction f = function
| HandleAsync (x, next) -> HandleAsync (x, next >> f)
| SendOutAsync (x, next) -> SendOutAsync (x, next >> f)
type PipeProgram<'msgIn, 'msgOut, 'a> =
| Act of PipeInstruction<'msgIn, 'msgOut, PipeProgram<'msgIn, 'msgOut, 'a>>
| Stop of 'a
let rec bind f = function
| Act x -> x |> mapInstruction (bind f) |> Act
| Stop x -> f x
type PipeBuilder() =
member __.Bind (x, f) = bind f x
member __.Return x = Stop x
member __.Zero () = Stop ()
member __.ReturnFrom x = x
let pipe = PipeBuilder()
let handleAsync msgIn = Act (HandleAsync (msgIn, Stop))
let sendOutAsync msgOut = Act (SendOutAsync (msgOut, Stop))
这篇文章是我根据这篇文章编写的。
然而对我来说,很重要的一点是将这些方法异步化(最好使用Task
,但Async
也可以),但是当我为我的pipeline
创建一个构建器时,我不知道如何使用它——我该如何等待一个Task<'msgOut>
或者Async<'msgOut>
,使其可以发送并等待这个“发送”任务?
现在我有以下这段代码:
let pipeline log msgIn =
pipe {
let! msgOut = handleAsync msgIn
let result = async {
let! msgOut = msgOut
log msgOut
return sendOutAsync msgOut
}
return result
}
这段代码返回 PipeProgram<'b, 'a, Async<PipeProgram<'c, 'a, Async>>>
。
pipe
计算构建器),这样我们就可以尝试运行它吗? - Tomas Petricek