看着:
member this.PostAndReply : (AsyncReplyChannel<'Reply> -> 'Msg) * ?int -> 'Reply
我无法弄清楚为什么签名对我来说非常直观。我们想要做的是向代理发布消息,然后等待回复。 为什么我们必须给他一个奇怪的功能作为'信息'?
再次查看此MSDN代码段:
let rec loop() =
printf "> "
let input = Console.ReadLine()
printThreadId("Console loop")
let reply = agent.PostAndReply(fun replyChannel -> input, replyChannel)
if (reply <> "Stopping.") then
printfn "Reply: %s" reply
loop()
else
()
loop()
我更喜欢这样的事情:
member this.PostAndReply : 'Msg * ?int -> 'Reply
由于
答案 0 :(得分:9)
当你第一次看到它时,这种类型的签名看起来很混乱,但它确实有意义。
F#库设计
背后的想法是,当你致电PostAndReply
时,你需要给它一个功能:
'Msg
的消息(将发送给代理)AsyncReplyChannel<'Reply>
的值)。 您构建的消息需要包含回复通道,但F#库不知道您希望如何表示消息(因此它不知道您希望如何在消息中存储回复通道)。因此,库会要求您编写一个函数,在系统构造通道后为代理构造消息。
您的替代建议
您的建议存在的问题是,如果PostAndReply
的类型为'Msg -> 'Reply
,则代理在调用Receive
后收到的消息将属于以下类型:
'Msg * AsyncReplyChannel<'Reply>
...因此,收到代理的每条消息都必须携带一个回复发送回复的频道。但是,您可能不希望为每个收到的消息发送回复,因此这不会真正起作用。也许你可以使用类似的东西:
'Msg * option<AsyncReplyChannel<'Reply>>
...但这只是变得越来越复杂(它仍然不太正确,因为你只能回复来自'Msg
的一些消息,但不能回复所有消息。)