F#:相当于OCaml Async

时间:2014-07-24 23:21:15

标签: asynchronous f# ocaml

F#是否与OCaml的异步库等效?具体来说,是否能够在填充时轻松创建延迟值并执行函数?

特别是,我想等到特定引用发生变化,然后再做一些事情。在OCaml中,我通过制作一个ivar并调用它的读取功能来做到这一点;我怎么能在F#中做到这一点?

2 个答案:

答案 0 :(得分:15)

简短回答

是的,我的Hopac图书馆是Jane Street的Async图书馆和F#的asynchronous workflows的近亲。 Hopac基于Concurrent ML(CML),并且可以说(在技术术语而不是意见问题上)目前提供了比其中任何一种更具表现力的编程模型。

更长的答案

Jane Street的Async的Deferred非常像.Net' Task。两者基本上都是comonadic抽象,顶部写着monadic层。

在Hopac中,与Deferred最相关的实际上是Promise。但是,Hopac并没有直接为Promises提供monadic层。当然,你可以很容易地写一个,但我建议你坐一会儿。相反,Hopac提供Job monad用于编码轻量级线程。这与how F#'s asynchronous workflows are defined类似,在我的主观意见中感觉更自然和easier to reason about

Jane Street的Async' Ivar是Hopac IVar的近亲。两者都来自同一血统。

使得CML和Hopac比Jane Street的Async和F#异步工作流更具表现力的是同步事件(CML)或alternatives(Hopac)组合器的可用性。使用这些多种并发协议可以封装为一流的,可扩展的(高阶),选择性操作。

CML&和Hopac的同步channels支持简单会合,这意味着通信的两端在通信发生时都是一致的。反过来,这有一些有趣的应用程序,例如能够实现支持垃圾收集发布 - 订阅样式通信的Multicast channels,而无需明确取消订阅(与Rx IObservable对比 - { {3}})。

具体答案

这是一个F#交互式会话,首先定义一个IVar,然后启动一个并发作业,该作业读取IVar的值并打印一条消息。最后,IVar被写入一个值:

> let nameVar : IVar<string> = ivar () ;;
val nameVar : IVar<string>
> start (nameVar |>> fun who -> printfn "Hello, %s!" who) ;;
val it : unit = ()
> run (nameVar <-= "Vesa") ;;
val it : unit = ()
> Hello, Vesa!

要生成此输出,使用IObserver脚本启动F#interactive。

答案 1 :(得分:0)

  

F#是否与OCaml的异步库等效?

F#内嵌了async等内容,例如MailboxProcessor

  

具体来说,是否能够在填充时轻松创建延迟值并执行函数?

.NET提供Task即可。