Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scala是一种存储状态的函数式方法_Scala_Functional Programming - Fatal编程技术网

scala是一种存储状态的函数式方法

scala是一种存储状态的函数式方法,scala,functional-programming,Scala,Functional Programming,我想用函数的方式在scala中存储一个状态(key->value)。我可能是在奥德斯基的课上学的,但已经记不住了 这是我的非功能性方法 import org.scalatest.{FunSuite, Matchers} trait EventHandler class StatefulNonFn { type EventName = String private var state = Map.empty[EventName, EventHandler] def updat

我想用函数的方式在scala中存储一个状态(
key->value
)。我可能是在奥德斯基的课上学的,但已经记不住了

这是我的非功能性方法

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
  }

}
我的一个尝试是将状态设置为“函数
EventName
和previousState”,这很有意义,但现在我不知道如何存储这些所有状态

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

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")

  }

}

我不确定,也许有些东西最终必须是可变的。在上述情况下,如何存储以前的状态?而不是每次调用都由客户机提供。因为状态可以从5个独立的客户端进行更新,而不需要知道以前的状态。

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

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

所以像Haskell这样严格的纯语言是通过返回动作(或计划,或动作描述…)而不是执行它们来实现的。运行时执行这些操作,因此您有两件事:

  • 你纯洁性感的节目

  • 运行时,负责做肮脏的事情

  • 然而Scala并不只是希望您返回操作,以便运行时执行它们。。。你需要自己做

    也就是说,如果你不想去黑暗的地方,你的解决方案是完全可以的。否则,我建议您阅读约翰·德戈斯(John Degoes)的一篇文章,这篇文章基本上解释了如何做您想做的事情(通过同时定义freemonad是什么)