正确使用可变/不可变列表
目前,我试图理解 Scala 中的函数式编程,但遇到了一个我自己无法解决的问题。
想象一下以下情况:
您有两个类:Controller 和 Bot。 机器人是一个独立的Actor,由控制器启动,执行一些昂贵的操作并将结果返回给控制器。因此,控制器的目的很容易描述:实例化Bot的多个对象,启动它们并接收结果。
到目前为止,一切都很好;我可以在不使用任何可变对象的情况下实现这一切。
但是,如果我必须存储机器人返回的结果,以便稍后将其用作另一个机器人的输入(稍后意味着我不知道什么时候编译时!)?
使用可变列表或集合执行此操作相当容易,但我在代码中添加了很多问题(因为我们在这里处理并发)。
遵循 FP 范式,是否可以通过安全地使用不可变对象(列表...)来解决这个问题?
顺便说一句,我是 FP 的新手,所以这个问题可能听起来很愚蠢,但我不知道如何解决这个问题:)
At the moment, Im trying to understand Functional Programming in Scala and I came across a problem I cannot figure out myself.
Imagine the following situation:
You have two classes: Controller and Bot. A Bot is an independent Actor which is initiated by a Controller, does some expensive operation and returns the result to the Controller. The purpose of the Controller is therefore easy to describe: Instantiate multiple objects of Bot, start them and receive the result.
So far, so good; I can implement all this without using any mutable objects.
But what do I do, if I have to store the result that a Bot returns, to use it later as input for another Bot (and later on means that I don't know when at compile time!)?
Doing this with a mutable list or collection is fairly easy, but I add a lot of problems to my code (as we are dealing with concurrency here).
Is it possible, following the FP paradigm, to solve this by using immutable objects (lists...) safely?
BTW, im new to FP, so this question might sound stupid, but I cannot figure out how to solve this :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
演员通常有内部状态,他们自己就是可变的野兽。请注意,演员不是 FP 的东西。
您描述的设置似乎依赖于可变控制器,并且很难用默认情况下不非严格的语言来绕过它。不过,根据您所做的事情,您可以依赖未来。例如:
在本例中 - 因为
!!
返回一个Future
-v1
、v2
和v3
将并行计算。消息 Fn4 正在接收作为 future 应用的参数,这意味着它将等到所有值都计算完毕后才开始计算。同样,只有在计算出 v4 后才会发送回复,因为 future 也已被应用。
执行这些操作的真正函数式方法是函数式响应式编程,简称 FRP。这是与演员不同的模型。
不过,Scala 的优点在于您可以将这些范例组合到更适合您的问题的程度。
Actors usually have internal state, being, themselves, mutable beasts. Note that actors are not a FP thing.
The setup you describe seems to rely on a mutable controller, and it is difficult to get around it in a language that is not non-strict by default. Depending on what you are doing, though, you could rely on futures. For example:
In this case -- because
!!
returns aFuture
--v1
,v2
andv3
will be computed in parallel. The messageFn4
is receiving as parameters the futures applied, meaning it will wait until all values are computed before it starts computing.Likewise, the reply will only be sent after
v4
has been computed, as the future has been applied for as well.A really functional way of doing these things is the functional reactive programming, or FRP for short. It is a different model than actors.
The beauty of Scala, though, is that you can combine such paradigms to the extent that better fits your problem.
这就是类似 Erlang 的 actor 在 Scala 中的样子:
This is how an Erlang-like actor could look in Scala: