【问题标题】:Continuous state events with State Monad使用 State Monad 的连续状态事件
【发布时间】:2015-12-15 09:32:16
【问题描述】:

考虑以下状态机:

class AudioRecorder {
  private var currentState = Idle

  def buttonTapped() = currentState match {
    case Idle => 
      currentState = Recording
      // start recording...

    case Recording =>
      currentState = Stopped
      // stop recording... 
  }
}

它有效,但有状态且丑陋。

不幸的是,我有很多情况需要处理这种带有连续事件状态机,尤其是在UI设置中。

似乎State Monad 是解决此问题的方法,但到目前为止,根据我的学习,它只有在您可以预先实际布局所有 状态事件 序列以便您可以连接它们时才有用一直到flatMap,但不是当 状态事件 是连续的和非确定性的,因为在这种情况下(当用户点击时) - 但如果我错了,请纠正我。

虽然我不太确定我问的问题是否正确,但是,

有没有更好的方法来为这种状态机建模,这种状态机会随着连续和非确定性事件改变其行为?


我已经用 Actor Model 使用 akka 在服务器端对此进行了建模,但我还没有看到有人在 UI 设置中使用 Actor 模型。


另外值得注意的是,AudioRecorder 不能在每个 buttonTapped 事件上重新创建以返回一个新实例(这可能会使状态问题消失),因为它保留了许多其他状态太昂贵而无法实现在每个信号上重新创建。

【问题讨论】:

  • Akka FSM 隐式存储 currentState 不是吗?
  • @Mr.V.我不太确定,但可能。我更多的是寻找一种不易出错的模式,如果这意味着使用另一个库来为我隐藏状态,那么这对我来说很好。但是我不认为akka在UI中很有用
  • 你研究过 rxscala 吗?
  • @ziggystar 是的。事实上,我的整个应用程序都依赖 RxScala 来支持 MVVM 模式。据我所知,如果我是正确的,这与 FRP 正在解决的问题不同。但是你有解决这个问题的想法吗?
  • 我认为您需要澄清“连续”和“非确定性”的含义。你的意思是异步的?那么一个解决方案就是 FRP。

标签: scala state monads state-machine state-monad


【解决方案1】:

将 FRP 与 rxscala 一起使用,您可以封装可变对象并将其隐藏。

它可能如下所示(未编译的代码):

class FrpRecorder(button: Observable[Unit]) {
  private val recorder = new AudioRecorder

  button.subscribe(_ => recorder.buttonTapped())

  val recordingLength: Observable[Double] = 
    interval("100ms").map(_ => recorder.recordingLength)

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    相关资源
    最近更新 更多