F#: 相当于 OCaml 的 Async

5

F#是否有类似于OCaml的Async库的等效物?具体而言,是否有轻松创建Deferred值并在它们填充时执行函数的能力?

特别是,我想等待特定引用的更改,然后执行某些操作。在OCaml中,我会通过创建一个ivar并调用其读取函数来实现此目的;在F#中我该如何做呢?


2
“异步工作流程”是F#的一个重要卖点。我不能说你可以直接翻译,但你几乎肯定会找到相应的东西。 - ChaosPandion
听起来你在问有关 System.Lazy 的内容(另请参见 lazy 关键字)。 - ildjarn
@ildjarn 嗯,我不确定。在我看来,那似乎是“这是一件事,请等到我准备好再评估它”;我想要的是“启动这个事情,告诉我何时准备好了。” - linkhyrule5
请澄清一下并提供链接或代码示例,以便我们可以学习或提供帮助。 - sgtz
1
@linkhyrule5пјҡйӮЈеә”иҜҘжҳҜ Task<T>гҖӮеҸҰиҜ·еҸӮйҳ… Async.AwaitTaskгҖҒAsync.StartAsTask е’Ң Async.StartChildAsTaskгҖӮ - ildjarn
2个回答

15

简短回答

是的,我的Hopac库与Jane Street的Async库和F#的异步工作流等许多库有着密切关系。 Hopac基于Concurrent ML(CML),可以说(从技术术语而非观点的角度)目前提供比它们更具表现力的编程模型。

详细回答

简街公司的Async的Deferred与.Net的Task类似。两者本质上都是具有单子层的共函子抽象,上面写着单子层。
在Hopac中,最接近Deferred的相对应物实际上是Promise。然而,Hopac并没有直接为Promises提供单子层。当然,你可以很容易地编写一个,但我建议先搁置一段时间。相反,Hopac为编码轻量级线程提供了Job单子。这类似于F#异步工作流程的定义方式,在我的主观意见中感觉更自然和更容易理解
Jane Street的Async的Ivar是Hopac的IVar的近亲。两者都来自同一血统。
CML和Hopac比Jane Street的Async和F#的异步工作流更具表现力的原因是它们提供了用于同步事件(CML)或替代方案(Hopac)的组合子。使用这些组合子可以将许多种并发协议封装为一流,可扩展(高阶),选择性操作。

CML和Hopac的同步通道支持简单会合,这意味着通信双方都同意何时进行通信。这反过来又有一些有趣的应用,比如实现多播通道,支持可垃圾回收的发布-订阅式通信,无需显式取消订阅(与Rx IObservable-IObserver相比)。

具体回答

这是一个 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!

为了产生这个输出,使用Hopac.fsx脚本启动了F#交互环境。

0
F#有没有类似OCaml的异步库呢?
F#内置了async等功能,还有MailboxProcessor等更多功能。
具体来说,能否方便地创建Deferred值并在其填充时执行函数呢?
.NET提供了可以做到这一点的Task

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接