首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala中的通用有限状态机(Transducer)

Scala中的通用有限状态机(Transducer)
EN

Stack Overflow用户
提问于 2013-08-14 08:36:37
回答 1查看 4.4K关注 0票数 10

在Scala中实现有限状态机(或有限状态传感器)的一般方法是什么?

我经常发现自己需要状态机实现。我的典型实现如下

代码语言:javascript
复制
object TypicalFSM { // actually — finite state transducer
  type State
  case object State1 extends State
  case object State2 extends State
  type Message
  case object Message1 extends Message
  type ResultMessage
  case object ResultMessage1 extends ResultMessage
}

import TypicalFSM._

class TypicalFSM extends ((Message) =>Seq[ResultMessage]){
  var state:State = State1

  def apply(message:Message):Seq[ResultMessage] = (state, message) match {
    case (State1, Message1) =>
      state = State2
      Seq(ResultMessage1, ResultMessage2)
  }
}

我不喜欢的是可变的var,它使解决方案线程不安全。另外,FSM的拓扑结构也不清楚。

  1. 如何以功能的方式创建FSM?
  2. .dot格式中绘制FSM-图也是非常好的。
  3. Akka FSM有一个很好的特性,允许将某些数据与国家相关联,而不仅仅是给出对象名称。这也是值得赞赏的。(然而,Akka FSM并不总是方便使用,因为它是异步的,有时还有点重。)
EN

回答 1

Stack Overflow用户

发布于 2014-02-22 22:52:39

这可能不是你想要的,但我认为这是一个有趣的概念。

代码语言:javascript
复制
object TypicalFSM {

  sealed trait State
  final class State1 extends State
  final class State2 extends State

  sealed trait Message
  case class Message1(s: String) extends Message
  case class Message2(s: String) extends Message

  sealed trait ResultMessage
  object ResultMessage1 extends ResultMessage
  object ResultMessage2 extends ResultMessage
}

import TypicalFSM._

case class Transformation[M <: Message, From <: State, To <: State](
    f:M => Seq[ResultMessage]) {

  def apply(m:M) = f(m)
}

object Transformation {

  implicit def `message1 in state1` =
    Transformation[Message1, State1, State2] { m =>
      Seq(ResultMessage1, ResultMessage2)
    }

  implicit def `message1 in state2` =
    Transformation[Message1, State2, State2] { m =>
      Seq(ResultMessage1)
    }

  implicit def `message2 in state2` =
    Transformation[Message2, State2, State1] { m =>
      Seq(ResultMessage2)
    }
}

class TypicalFSM[CurrentState <: State] {

  def apply[M <: Message, NewState <: State](message: M)(
    implicit transformWith: Transformation[M, CurrentState, NewState]) = {

    this.asInstanceOf[TypicalFSM[NewState]] -> transformWith(message)
  }
}

用法如下:

代码语言:javascript
复制
def test() = {
  val s1 = new TypicalFSM[State1]
  // type of s1: TypicalFSM[State1]

  val (s2, r1) = s1(Message1("m1"))
  // type of s2: TypicalFSM[State2]

  val (s3, r2) = s2(Message1("m1"))
  // type of s2: TypicalFSM[State2]

  val (s4, r3) = s2(Message2("m2"))
  // type of s2: TypicalFSM[State1]

  // val (s5, r4) = s4(Message2("m2"))
  // Fails with:
  // 'No transformation available for TypicalFSM.Message2 in TypicalFSM.State1'
  // type of s5: TypicalFSM[State1]
}

您的用例将强烈地决定这个概念中代码的结构。用例确实决定了需要保留多少类型信息。

I这个概念是因为状态一直使用类型系统,并且在编译时报告非法转换。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18226863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档