2015年6月8日月曜日

scala関数型デザイン&プログラミング P112

exercise 6.11 Stateの使用に慣れるために、単純なスナックの自動販売機をモデリングする有限状態オートマンを実装せよ。この自動販売機では、2種類の入力を使用する。すなわち硬貨を投入することができ、ハンドルを回してスナックを取り出すことができる。自動販売機はロックされた状態とロックが解除された状態のどちらかになる。また、残りのスナックの数と自動販売機に投入された硬貨の数も追跡する。

解答は次のようになっている。書籍で断っている通り難問。sequenceの使い方がいまいちわからない。inputsからのi:Inputを逐次処理していくのだろうか。modfyで、状態を変化させるんだろうけれど。これだけの式で、List[Input]の中のInputをすべて逐次処理して、最終結果をs<-getで得るということなんだろうか?
sealed trait Input
case object Coin extends Input
case object Turn extends Input

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

object Candy {
  def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
    _ <- sequence(inputs.map(i => modify((s: Machine) => (i, s) match {
      case (_, Machine(_, 0, _)) => s
      case (Coin, Machine(false, _, _)) => s
      case (Turn, Machine(true, _, _)) => s
      case (Coin, Machine(true, candy, coin)) =>
        Machine(false, candy, coin + 1)
      case (Turn, Machine(false, candy, coin)) =>
        Machine(true, candy - 1, coin)
    })))
    s <- get
  } yield (s.coins, s.candies)
}

0 件のコメント:

コメントを投稿