Skip to content

Instantly share code, notes, and snippets.

@jrwest
Created July 4, 2012 02:04
Show Gist options
  • Select an option

  • Save jrwest/943f6fba5cf6f8f31a9f to your computer and use it in GitHub Desktop.

Select an option

Save jrwest/943f6fba5cf6f8f31a9f to your computer and use it in GitHub Desktop.
import scalaz._
import Scalaz._
trait MaybeT[M[_],A] {
import MaybeT._
def run: M[Maybe[A]]
def fold[B](just: A => B, nothing: => B)(implicit F: Functor[M]): M[B] = F.map(run)(_.fold[B](just, nothing))
def map[B](f: A => B)(implicit F: Functor[M]): MaybeT[M,B] = {
val a = this
new MaybeT[M,B] {
val run: M[Maybe[B]] = a.fold(
just = v => MaybeT.Just(f(v)),
nothing = MaybeT.Nothing[B]
)
}
}
def flatMap[B](f: A => MaybeT[M,B])(implicit M: Monad[M]): MaybeT[M,B] = {
val a = this
new MaybeT[M,B] {
val run: M[Maybe[B]] = M.bind(a.run)((_: Maybe[A]).fold[M[Maybe[B]]](
just = v => f(v).run,
nothing = M.point(MaybeT.Nothing[B])
))
}
}
def getOrElse(default: => A)(implicit F: Functor[M]): M[A] = fold(identity, default)
}
object MaybeT {
type Maybe[A] = MaybeT[Id,A]
def apply[M[_]: Monad, A](ma: M[Maybe[A]]): MaybeT[M,A] = new MaybeT[M,A] {
val run = ma
}
def Just[A](v: A): Maybe[A] = new MaybeT[Id,A] {
val run: Id[Maybe[A]] = Monad[Id].point(this)
override def fold[B](just: A => B, nothing: => B)(implicit F: Functor[Id]): Id[B] = just(v)
}
def Nothing[A]: Maybe[A] = new MaybeT[Id,A] {
val run: Id[Maybe[A]] = Monad[Id].point(this)
override def fold[B](just: A => B, nothing: => B)(implicit F: Functor[Id]): Id[B] = nothing
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment