我如何为一个项目实现一个纯功能性的体系结构,该项目包含随着时间的推移使用Scala和scalaz而变化的对象

我如何为一个项目实现一个纯功能性的体系结构,该项目包含随着时间的推移使用Scala和scalaz而变化的对象,scala,functional-programming,scalaz,Scala,Functional Programming,Scalaz,我有一个项目,我正在实施一个自动售货机。我有一个物体贩卖机,里面有另一个物体叫CoinOp。我想让CoinOp对象接受不同价值的硬币。自动售货机可以让CoinOp告诉它用户输入了多少钱。要想真正起作用,硬币必须能够改变里面的钱的数量 自动售货机如下所示: class VendingMachine { val coinOp = new CoinOp() } case class CoinOp(money: Float) { def addCoins(amount: Float):

我有一个项目,我正在实施一个自动售货机。我有一个物体贩卖机,里面有另一个物体叫CoinOp。我想让CoinOp对象接受不同价值的硬币。自动售货机可以让CoinOp告诉它用户输入了多少钱。要想真正起作用,硬币必须能够改变里面的钱的数量

自动售货机如下所示:

class VendingMachine {
    val coinOp = new CoinOp()
}
case class CoinOp(money: Float) {
    def addCoins(amount: Float): CoinOp = CoinOp(money + amount)
}
我想以一种功能性的方式来实现这一点,这会立即将CoinOp的实现作为一个选项删除:

class CoinOp {
    var money = 0.0f

    def addCoins(amount: Float) = money += amount
}
相反,我需要这样做:

class VendingMachine {
    val coinOp = new CoinOp()
}
case class CoinOp(money: Float) {
    def addCoins(amount: Float): CoinOp = CoinOp(money + amount)
}
我知道我可以用scalaz做这样的事情。scalaz中的实现并不是这个问题的焦点

我的问题是:考虑到我可以在功能上更新CoinOp拥有的金额,我如何显示已经改变的自动售货机

在addCoins中创建新的CoinOp对象非常棒,但它是一个新对象,并且不会改变VendingMachine引用的对象。这是很好的持久性,所有功能编程的一部分。但是,我需要自动售货机使用addCoins()创建的对象,而不是类定义中的对象。我该怎么做

我能想到的唯一一件事是将VendingMachine中的coinOp对象设置为var,然后我可以设置它以响应对coinOp#addCoins的调用。但这对我来说似乎不是个好办法


有人能解释一下类似的东西是如何设置的吗?

如果你想做函数式编程,你就要尽可能多地使用没有副作用和不可变结构的方法,就像你的

case class CoinOp(money: Float) {
  def addCoins(amount: Float): CoinOp = CoinOp(money + amount)
  def addCoins(amount: CoinOp): CoinOp = CoinOp(money + amount.money)
}
这样,正如您所说,当调用
addCoins
方法时,您将得到返回的新
CoinOp
实例

但这里的问题是你的任务。拥有自动售货机意味着你需要保持某种状态。不幸的是,状态是,
var

因此,如果您不需要线程安全性,只需创建类型为
CoinOp
的私有变量,并在添加资金时,将
CoinOp
的另一个实例分配给该变量。这样,您的
CoinOp
类将是不可变的,但
VendingMachine
将有一个状态且是可变的

class VendingMachine{
  var funds: CoinOp = CoinOp(0)

  def addFunds(amount: CoinOp): CoinOp = {
    funds = funds.addCoins(amount.money)
    // or rather use addCoins(CoinOP):
    // funds = funds.addCoins(amount)
  }
}

如果您想同步访问您的资金状态-Scala的方式是Akka Actor,将您的状态保持在自身内部

我觉得这根本解决不了问题。它不会移除状态,只是将它移动到其他地方。正如我所理解的,状态是一些问题的本质。这就是为什么像阿克卡演员这样的图书馆存在的原因。因此,拥有状态是自动售货机本质的一部分。您需要处理它。OP没有询问任何关于在并发上下文中管理状态的问题,这就是为什么您首先要寻找参与者。看起来您正在寻找状态Monad。