Back to Fpinscala

11.Answer

answerkey/state/11.answer.md

latest710 B
Original Source
scala
enum Input:
  case Coin, Turn

case class Machine(locked: Boolean, candies: Int, coins: Int)

object Candy:
  def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = 
    for
      _ <- State.traverse(inputs)(i => State.modify(update(i)))
      s <- State.get
    yield (s.coins, s.candies)

  val update = (i: Input) => (s: Machine) =>
    (i, s) match
      case (_, Machine(_, 0, _)) => s
      case (Input.Coin, Machine(false, _, _)) => s
      case (Input.Turn, Machine(true, _, _)) => s
      case (Input.Coin, Machine(true, candy, coin)) =>
        Machine(false, candy, coin + 1)
      case (Input.Turn, Machine(false, candy, coin)) =>
        Machine(true, candy - 1, coin)