12

看着:

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

谢谢

4

1 回答 1

9

当您第一次看到这种类型签名时,它看起来很混乱,但它确实有意义。

F# 库设计
背后的想法是,当你调用时,PostAndReply你需要给它一个函数

  • 构造一个类型的消息'Msg(发送给代理)
  • 在 F# 运行时构建用于将消息发送回调用者的通道之后(通道表示为 type 的值AsyncReplyChannel<'Reply>)。

您构建的消息需要包含回复通道,但 F# 库不知道您希望如何表示您的消息(因此它不知道您希望如何在消息中存储回复通道)。因此,该库要求您编写一个函数,该函数将在系统构建通道后为代理构建消息。

您的替代建议您
的建议 的问题是,如果PostAndReply有 type 'Msg -> 'Reply,代理在调用后收到的消息Receive将属于以下类型:

'Msg * AsyncReplyChannel<'Reply>

...因此,接收到代理的每条消息也必须携带一个用于发送回复的通道。但是,您可能不想为收到的每条消息都发回回复,所以这实际上行不通。也许你可以使用类似的东西:

'Msg * option<AsyncReplyChannel<'Reply>>

...但这只是变得越来越复杂(而且仍然不太正确,因为您只能回复来自 的一些消息'Msg,但不能回复所有消息)。

于 2012-02-29T15:10:56.443 回答