我想使用函数方式在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个单独的客户端更新,而不知道以前的状态。
答案 0 :(得分:1)
事实证明,如果你想做一些有用的程序,你需要突变,你需要状态。您需要执行IO,例如保存到数据库中(每次执行时都可以返回一些不同的ID),或者获取随机数,当前时间戳或打印到控制台等等。
如果你正在进行函数式编程,那就不是要做纯粹的,确定性的,全部的东西。它是关于隔离副作用(如突变和状态)。
如Haskell这样的严格纯语言通过返回动作(或计划或动作描述......)而不是执行它们来做到这一点。运行时执行这些操作,因此您有两件事:
你的纯粹和性感的节目
运行时,负责做脏事。
然而,Scala并不只是希望你返回动作,以便运行时执行它们......你需要自己动手。
话虽如此,如果你不想去黑暗的地方,你的解决方案是完全可以的。否则,我建议你阅读约翰·德戈斯的一篇文章this,它基本上解释了如何做你想做的事情(同时定义一个freemonad是什么)。