5. モナド(Monad)とは
一言で言えば、 flatMapできる型クラス(type class)。
F[A] => (A => F[B]) => F[B]
型クラスFunctor, Applicativeの上位互換。
// scalaz.Monad
trait Monad[F[_]] extends Applicative[F] with Bind[F] {
abstract def bind[A, B](fa: F[A])(f: (A) ⇒ F[B]): F[B]
abstract def point[A](a: ⇒ A): F[A]
...
}
-- Haskell
class Applicative m => Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
return :: a -> m a
...
7. Functorの map
F[A] => (A => B) => F[B]
にあたる。scalaz.Functor.map
val n: Option[Int] = Some(1)
val f: Int => String = x => x.toString
// Option#map
n.map(f)
// Option#flatMap による実装
n.flatMap { a =>
Some(f(a))
}
// for式による実装
for {
a <- n
} yield f(a)
8. Applicativeの ap / <*>
F[A] => F[A => B] => F[B]
, にあたる。scalaz.Apply.apscalaz.syntax.ApplyOps.<*>
val n: Option[Int] = Some(1)
val f: Option[Int => String] = Some(x => x.toString)
// Option#flatMap, Option#map による実装
n.flatMap { a =>
f.map { g =>
g(a)
}
}
// for式による実装
for {
a <- n
g <- f
} yield g(a)
9. Monadの flatMap / bind / >>=
F[A] => (A => F[B]) => F[B]
, にあたる。scalaz.Bind.bindscalaz.syntax.BindOps.>>=
val n: Option[Int] = Some(1)
val f: Int => Option[String] = x => Some(x.toString)
// Option#flatMap
n.flatMap(f)
// for式による実装
for {
a <- n
b <- f(a)
} yield b