Scala における実用上のモナドの価値 val xs: Either[String, Int] = Right(1) val ys: Either[String, Int] = Right(2) for { x <- xs y <- ys } yield x + y // res0: scala.util.Either[String,Int] = Right(3)
Scala における実用上のモナドの価値 val xs: List[String] = List("foo", "bar") val ys: List[String] = List("!", "?") for { x <- xs y <- ys } yield x + y // res3: List[String] = List(foo!, foo?, bar!, bar?)
【抽象的なモナドの実装】for 式で合成するために // for 式で合成ができない for { i <- Maybe.just(1) j <- Maybe.just(2) } yield i + j // i <- Maybe.just(1) // ^ // On line 2: error: value flatMap is not a member of Maybe[Int] // j <- Maybe.just(2) // ^ // On line 3: error: value map is not a member of Maybe[Int]
【具体的なモナドの実装】実装方法 sealed abstract class Maybe[A] { def flatMap[B](f: A => Maybe[B]): Maybe[B] = this match { case Just(a) => f(a) case Empty() => Empty() } // デフォルト実装 def map[B](f: A => B): Maybe[B] = flatMap(a => Maybe.pure(f(a))) } case class Just[A](a: A) extends Maybe[A] case class Empty[A]() extends Maybe[A]
【抽象的なモナド】MonadTransformer val prog: IO[Option[Int]] = for { // IO[A] の合成 nOpt <- readInt mOpt <- readInt } yield for { // Option[A] の合成 n <- nOpt m <- mOpt } yield n + m