Unable to put Fsm instance in another class that doesn't have type parameter
Opened this issue · 2 comments
The Fsm[_]
class is type parameterized, so while doing this works:
case class Foo[S <: State](fsm: Fsm[S])
"test Foo" in {
val x = Foo[A](Fsm(A("a")))
val y = x.copy(fsm = x.fsm.transition(Iab("b")))
y.isInstanceOf[Foo[B]] shouldBe true
}
This doesn't work:
case class Bar(fsm: Fsm[_])
"test Bar" in {
val x = Bar(Fsm(A("a")))
val y = x.copy(fsm = x.fsm.transition(Iab("b")))
}
Compile error:
[error] could not find implicit value for parameter t: anduin.fsm.Transformation[_$1,Iab,TO]
[error] val y = x.copy(fsm = x.fsm.transition(Iab("b")))
Because of this fact, I'm unable to put the Fsm[_]
in a React case class State
😞
/cc @nhap96 & @ngthanhtrung to see if there's anything we could do to improve this
Thanks for the FSM implementation.
Lets say I have List(Input) where I have to loop thru each Input record and depending on previous state, transition to next state based on some conditions.
How do I implement this based on your FSM. Thanks in advance.
Example:
case class TuningEvent(eventType:String) extends Input
case object NONTUNED extends State
case object TUNED extends State
case object TRICK extends State
implicit val t_NONTUNED_TUNED = Transformation1[NONTUNED.type , TuningEvent , TUNED.type]((_, ) => TUNED)
implicit val t_TUNED_TRICK = Transformation1[TUNED.type, TuningEvent, TRICK.type]((, _) => TRICK)
val inputList = List(TuningEvent("PLAY"),TuningEvent("REPLAY"))
var newFsm = Fsm(NONTUNED) // Begin with NONTUNED always
for (input <- inputList) {
println(newFsm.transition(input))
}
My expected output should be
Fsm(TUNED)
Fsm(TRICK)
But Actual Output:
Fsm(TUNED)
Fsm(TUNED)
@nats82 thanks for trying our this project.
The reason for the output you see is that you always invoke transition()
from the same object (which is newFsm
), hence receiving the same output. You will need to invoke transition on the returned Fsm
of a transition, e.g. newFsm.transition(TurnEvent("PLAY")).transition(TurnEvent("REPLAY"))
will yield Fsm(TRICK)
.
Looping through a list of TuningEvent
won't work yet, and the reason is that everything is checked at compile time, but at compile time, you don't know how many TuningEvent
are there, hence the compiler can't determine what the final state of the Fsm
will be. The root cause of this is the same as the problem I described above, and unfortunately, we don't have an answer for that yet. This might be an example of pushing too far into an extreme (everything is statically checked), and make it not usable in practice 😞