scalaz.StateT で scalaz.State と Option を組み合わせる
scalaz の ExampleState に StateT のサンプルが無かったので試してみた。
気が向いたら、そもそも State モナドって何よ?という所から説明書くかも。
package com.github.cooldaemon.try_scalaz import scalaz._ object TryState { import Scalaz._ def run { def initO = stateT[Option, Int, Int]((s: Int) => if (s % 2 == 0) Some((s, s)) else None ) initO ! 1 assert_=== None initO ! 2 assert_=== Some(2) def putO(s: Int) = stateT[Option, Int, Unit](_ => if (s % 2 == 0) Some((s, ())) else None ) putO(1) ~> 0 assert_=== None putO(2) ~> 0 assert_=== Some(2) val res1 = for { x <- initO; _ <- putO(4) } yield x res1 ! 1 assert_=== None res1 ! 2 assert_=== Some(2) res1 ~> 2 assert_=== Some(4) def modifyO(f: Int => Int) = initO flatMap (s => stateT[Option, Int, Unit](_ => if (s % 2 == 0) Some((f(s), ())) else None )) modifyO(s => s + 1) ~> 1 assert_=== None modifyO(s => s + 1) ~> 2 assert_=== Some(3) def getsO = stateT[Option, Int, Int]((s: Int) => Some((s, s)) ) val res2 = for { _ <- modifyO(s => s + 2); _ <- modifyO(s => s + 1); x <- getsO } yield x res2 ! 1 assert_=== None res2 ! 2 assert_=== Some(5) val res3 = for { _ <- res1; x <- res2 } yield x res3 ! 1 assert_=== None res3 ! 2 assert_=== Some(7) } }