I'm trying to understand and get comfortable with the State Monad so I'm basically following along by copying a preexisting example. The 'State' is just a door that opens if it's Pushed when closed and closes when Pulled if it's open. If it's Pushed when open or Pulled when closed, it does nothing. So the code below seems to work as expected.
def main(args: Array[String]): Unit = {
import Monad._
// Push to open, pull to close
case class Door(open: Boolean = false)
trait Action
case object Push extends Action
case object Pull extends Action
def update: Action => Door => Door = action => door => {
val curr = (action, door)
println(curr)
curr match {
case (Push, Door(op)) => if (op) door else Door(!op)
case (Pull, Door(op)) => if (op) Door(!op) else door
}
}
val sm = stateMonad[Door] // Code for 'stateMonad' not shown
def simulate(inputs: List[Action]) = for {
_ <- sm.sequence(inputs map (a => State.modify(update(a))))
s <- State.get
} yield ()
val actions = List(Push, Pull, Pull, Push)
val r = simulate(actions).run(Door())
println(r) }
// The code above results in:
(Push,Door(false))
(Pull,Door(true))
(Pull,Door(false))
(Push,Door(false))
((),Door(true))
However, if I change the first case statement to this:
case (Push, Door(op)) => if (op) door else Door(false)
Which I would think would be the same thing... // It results in:
(Push,Door(false))
(Pull,Door(false))
(Pull,Door(false))
(Push,Door(false))
((),Door(false))
This has got to be something really stoopid on my part, but I can't find and I don't otherwise have an explanation for what is going on. Can someone please help?
Thanks.