F#是否与OCaml的异步库等效?具体来说,是否能够在填充时轻松创建延迟值并执行函数?
特别是,我想等到特定引用发生变化,然后再做一些事情。在OCaml中,我通过制作一个ivar并调用它的读取功能来做到这一点;我怎么能在F#中做到这一点?
答案 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
即可。