scala功能方式存储状态

时间:2018-04-04 16:01:23

标签: scala functional-programming

我想使用函数方式在scala中存储状态(import org.scalatest.{FunSuite, Matchers} trait EventHandler class StatefulNonFn { type EventName = String private var state = Map.empty[EventName, EventHandler] def update(name: String): EventHandler = { state.get(name).fold { val handler = new EventHandler {} state += name -> handler handler }(eh => eh) } } class NonFunctionalStateSpec extends FunSuite with Matchers { test("stateful") { val stateResult = new StatefulNonFn().update("MusicAdded") stateResult.isInstanceOf[EventHandler] shouldBe true } } )。我可能刚刚在Odersky课堂上学过但不记得了。

这是我的非功能性方法;

EventName

我做的一个尝试是使状态成为“import org.scalatest.{FunSuite, Matchers} trait EventHandler class Stateful { type EventName = String private val stateFn = new ((String, Map[EventName, EventHandler]) => Map[EventName, EventHandler]) { override def apply(name: String, prevState: Map[EventName, EventHandler]): Map[EventName, EventHandler] = { val handler = new EventHandler {} prevState + (name -> handler) } } def initState = Map.empty[EventName, EventHandler] def update(name: String, prevState: Map[EventName, EventHandler]) = stateFn(name, prevState) } class FunctionalStateSpec extends FunSuite with Matchers { test("stateful") { val stateHelper = new Stateful() val stateResult = stateHelper.update("MusicAdded", stateHelper.initState) stateResult.keys.size shouldBe 1 val stateResult1 = stateHelper.update("MusicDeleted", stateResult) stateResult1.keys.size shouldBe 2 //what i obviously want is something like this without me wanting to store the previousStates //stateHelper.update("MusicAdded1") //stateHelper.update("MusicAdded2") } } 和previousState”的功能,这是有道理的,但现在我无法弄清楚如何存储所有状态?

我的第一个电话会很好,因为在这种情况下状态是空的。

results<-resamples(list(testindex["svm.pred"], testindex["rpart.pred"]))

我不确定,也许某些东西最终必须是可变的。如何在上述情况下存储以前的状态?没有客户是每次通话中提供它的人。因为状态可以从5个单独的客户端更新,而不知道以前的状态。

1 个答案:

答案 0 :(得分:1)

事实证明,如果你想做一些有用的程序,你需要突变,你需要状态。您需要执行IO,例如保存到数据库中(每次执行时都可以返回一些不同的ID),或者获取随机数,当前时间戳或打印到控制台等等。

如果你正在进行函数式编程,那就不是要做纯粹的,确定性的,全部的东西。它是关于隔离副作用(如突变和状态)。

如Haskell这样的严格纯语言通过返回动作(或计划或动作描述......)而不是执行它们来做到这一点。运行时执行这些操作,因此您有两件事:

  1. 你的纯粹和性感的节目

  2. 运行时,负责做脏事。

  3. 然而,Scala并不只是希望你返回动作,以便运行时执行它们......你需要自己动手。

    话虽如此,如果你不想去黑暗的地方,你的解决方案是完全可以的。否则,我建议你阅读约翰·德戈斯的一篇文章this,它基本上解释了如何做你想做的事情(同时定义一个freemonad是什么)。