sealed trait Maybe[+A]
case class Some[A](head: A) extends Maybe[A]
case object None extends Maybe[Nothing]
object Maybe {
implicit def maybeTMonad[M[_]: Monad]: Monad[({ type λ[ɑ] = M[Maybe[ɑ]] })#λ] =
new Monad[({ type λ[ɑ] = M[Maybe[ɑ]] })#λ] {
private lazy val m: Monad[M] = implicitly[Monad[M]]
def pure[A](a: A): M[Maybe[A]] =
if (a == null) m.pure(None) else m.pure(Some(a))
def flatMap[A, B](ma: M[Maybe[A]])(f: A => M[Maybe[B]]): M[Maybe[B]] =
.flatMap(ma) {
mmatch {
_ case Some(a) => f(a)
case None => m.pure(None)
}
}
}
implicit val maybeMonad: Monad[Maybe] = maybeTMonad[ID]
}
import Monad._
{
println for {
<- Some(6): Maybe[Int]
x <- Some(7): Maybe[Int]
y = x * y
z } yield z // Some(42)
}
This file is literate Scala, and can be run using Codedown:
$ curl \
https://earldouglas.com/posts/type-classes/applicative.md \
https://earldouglas.com/posts/type-classes/functor.md \
https://earldouglas.com/posts/type-classes/id.md \
https://earldouglas.com/posts/type-classes/monad.md \
https://earldouglas.com/posts/type-classes/maybe.md |
codedown scala | xargs -0 scala -nc -e
Some(42)