我一直试图找到任何讨论何时应该优先使用 monad 而不是 actor(在并发场景中)的内容,但我什么也没找到。特别是,我想知道反应性扩展(LINQ to Events)与 F# 的 MailboxProcessor 的使用。除了您可能有的任何哲学推理之外,请举例说明。
更新
为了更好的上下文,响应式扩展以 IObservable/IObserver 的形式实现延续 monad。我不一定说我必须使用 F#,只是 F# 在 .NET 语言中以 MailboxProcessor<'T> 的形式提供了具体的“参与者模型”。
我想要了解的是何时使用 monad(在本例中为延续 monad)与 actor 模型来实现并发目的。在单子(据我所知)不引入状态的情况下,参与者有自己的内部状态,可以根据需要进行修改以提供受保护的访问。
我见过很多同时使用两者的例子:Rx 和 node.js(CPS,不是真正的延续 monad)与 F# 的 MailboxProcessor 和 Scala 的 Akka 框架。我只是不知道为什么你会选择其中之一。
I've been trying to find anything that discusses when you should favor the use of monads over actors (in concurrency scenarios), but I've found nothing. In particular, I'm wondering about the use of the Reactive Extensions (LINQ to Events) vs. F#'s MailboxProcessor. Please give examples in addition to any philosophical reasoning you might have.
Update
For better context, the Reactive Extensions implement the continuation monad in the form of IObservable/IObserver. I'm not necessarily saying I have to use F#, just that F# has a concrete "actor model" available in a .NET language in the form of MailboxProcessor<'T>.
What I'm trying to understand is when to use a monad (in this case a continuation monad) vs. an actor model for concurrency purposes. Where the monad (as I understand it) doesn't introduce state, the actor has its own internal state that is modified as necessary to provide protected access.
I've seen a number of examples of using both: Rx and node.js (CPS, not really the continuation monad) vs. F#'s MailboxProcessor and Scala's Akka framework. I just don't know why you would choose one over the other.
发布评论
评论(4)
我将回答我自己的问题并说你应该同时使用两者。这是基于 Don Syme 的帖子。 MbP 使用异步计算来完成其工作,并且异步是线程感知的延续 monad。看起来您可以单独使用它来实现某些用途,但 MbP 绝对需要它。
我不太喜欢这个答案,我很高兴有人能更好地解释何时使用每个答案。更新:
请参阅MiniRx,现在是 FSharpx,用于使用
MailboxProcessor
实现的 Rx 样式 monad 的实现。由于 MailboxProcessor 本身是使用 async monad 实现的,因此它们确实可以一起工作。它们只是不同的抽象方式。I'm going to respond to my own question and say you should use both. This is based on Don Syme's post. A MbP uses the Async computation to do its work, and the Async is a thread-aware continuation monad. Looks like you can use it by itself for some uses, but the MbP definitely requires it.
I don't really like this answer, and I'd be happy for someone to respond with a better explanation of when to use each.Updated:
See MiniRx, which is now apart of FSharpx, for an implementation of an Rx-style monad implemented using
MailboxProcessor
. AsMailboxProcessor
is itself implemented using theasync
monad, these pieced to indeed work together. They are just different means of abstraction.您会接受来自 Scala 世界的答案吗?
如果您寻求“演员模型的纯功能替代品”,那么请参阅 Paul Chiusano 博客中的这篇精彩文章
pchiusano.blogspot.ro/2010/01/actors-are-not-good-concurrency-model.html
(存档于此处:http://archive.is/NxNLc)
以及下面的一些参考:
http://noelwelsh.com/programming/2013/03/ 04/为什么我不喜欢akka演员/
https://opencredo.com/akka-typed/
http://doc.akka.io/docs/akka/snapshot/scala/typed.html
具有价格合理的 monad 的可组合应用程序架构
概念Heather Miller 的“函数传递风格”可能是分布式函数式编程模型的关键。
SF Scala:Heather Miller,函数传递风格,分布式编程的新模型
< em>更新 12/2018:现在我们可以使用
Aecor
,它提供了以下方法:编程模型
实现业务域逻辑并>Akka
基于运行时
来源:https://pavkin.ru/aecor-part-3/, http://aecor.io
Would you accept answers from the Scala world?
If you seek "a purely functional alternative to actor model" then please see this great post from Paul Chiusano's blog
pchiusano.blogspot.ro/2010/01/actors-are-not-good-concurrency-model.html
(archived here: http://archive.is/NxNLc)
and some references below:
http://noelwelsh.com/programming/2013/03/04/why-i-dont-like-akka-actors/
https://opencredo.com/akka-typed/
http://doc.akka.io/docs/akka/snapshot/scala/typed.html
Composable application architecture with reasonably priced monads
The concept of "function passing style" from Heather Miller might be key to a distributed functional programming model.
SF Scala: Heather Miller, Function-Passing Style, A New Model for Distributed Programming
Update 12/2018 : now we can use
Aecor
which provide the means to:programming model
andAkka
basedruntime
Source: https://pavkin.ru/aecor-part-3/, http://aecor.io
请原谅我的新手,因为我刚刚学习 F#。
如果您有相关材料的链接,我很高兴看到使用 RX 代替 MailboxProcessor。
以我有限的理解;我会在自己的代码中选择 MbP,因为在 F# 中设置事件有点混乱(从本文中我可以了解到:MSDN)。并且您需要 RX 挂钩的事件,对吧?
与 MbP 一样,我所需要的只是消息的可区分联合,即收到给定消息时我希望执行的函数列表。以及处理此问题的邮箱处理器。
这一切在代码中看起来都非常整洁。我可以将我的 MbP 集中在一个模块中,然后我的“对象”模块看起来像
对于我来说,这看起来比我用事件编写代码时要整洁得多我链接到的 MSDN 文章中对此进行了描述。
虽然我只是一名 F# 大三学生,所以我的计算可能还有很大差距,这是一个外观和感觉的问题,而不是一个适合目的的选择(因为我没有资格做出这样的决定,但)
Please excuse my newbie-ness as I'm just learning F#.
I'm intrigued to see the use of RX in place of a MailboxProcessor, if you have any links to relevant materials.
With my limited understanding; I would choose MbP's in my own code as events are a bit messy to set up in F# (from what I can take from this article: MSDN). And you need events for RX to hook into right?
Where as with a MbP all I need is a discriminated union of messages, a list of functions I wish to be executed when a given message is received. And the mail box processor that handles this.
This all looks pretty neat in the code. I can bunch my MbP's together in a module then my "object" module looks like
For me this looks a lot neater than it would If I wrote my code with events as described in that MSDN article I linked to.
Though I am just an F# junior so I may be a miles off with my reckoning and it is a look-&-feel thing rather than a suitability-for-purpose choice (as I'm not qualified to make that call, yet)
我不确定这个问题是否有意义——有许多不同的单子(例如身份单子、列表单子、选项单子……),其中大多数与并发无关。此外,更多地了解您正在处理的特定场景会很有帮助——“并发”是一个有点模糊的话题。根据您想要实现的目标,F# 的
async
工作流程(基于Async
monad 构建)可能是您的最佳选择。如果您使用 F#,我建议不要直接使用 LINQ-to-anything,因为通过 F# 访问这些库有一种非常陌生的感觉。但是,您可以创建令人愉快的 F# 包装器(例如现有的 Seq 和 Observable 模块)。此外,对于单子类型,您可以创建一个计算表达式构建器(例如,您可以使用响应式扩展创建一个构建器,这将使您能够使用计算表达式来构建和组合 IObservable )。
I'm not sure that the question makes sense as phrased - there are many different monads (e.g. the identity monad, the list monad, the option monad, ...), most of which have nothing to do with concurrency. Furthermore, it would be helpful to know more about the particular scenario that you're dealing with - "concurrency" is a bit of a nebulous topic. Depending on what you're trying to achieve, F#'s
async
workflows (which are built on theAsync
monad) might be your best bet.If you're using F#, I'd recommend against using LINQ-to-anything directly, since those libraries have a very alien feel when accessed via F#. You could, however, create pleasant F# wrappers (such as the existing
Seq
andObservable
modules). Additionally, for monadic types, you could create a computation expression builder (e.g. you could create a builder using the Reactive Extensions which would enable you to use computation expressions to build and composeIObservable
s).