我如何为一个项目实现一个纯功能性的体系结构,该项目包含随着时间的推移使用Scala和scalaz而变化的对象
我有一个项目,我正在实施一个自动售货机。我有一个物体贩卖机,里面有另一个物体叫CoinOp。我想让CoinOp对象接受不同价值的硬币。自动售货机可以让CoinOp告诉它用户输入了多少钱。要想真正起作用,硬币必须能够改变里面的钱的数量 自动售货机如下所示:我如何为一个项目实现一个纯功能性的体系结构,该项目包含随着时间的推移使用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):
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。