Skip to content

Instantly share code, notes, and snippets.

@apruden
Created December 11, 2014 02:52
Show Gist options
  • Save apruden/c7655738acb244e1a3d3 to your computer and use it in GitHub Desktop.
Save apruden/c7655738acb244e1a3d3 to your computer and use it in GitHub Desktop.
Monad Transformers
case class Reader[C, A](g: C => A) {
def apply(c: C) = g(c)
def map[B](f: A => B): Reader[C, B] =
(c:C) => f(g(c))
def flatMap[B](f: A => Reader[C, B]): Reader[C, B] =
(c:C) => f(g(c))(c)
}
object Reader {
implicit def Reader[A,B](f: A => B): Reader[A,B] = Reader(f)
def pure[A, C](a: A): Reader[C,A] =
(c: C) => a
}
case class ReaderOptionT[C, R](g: Reader[C, Option[R]]) {
def map[B](f: R => B): ReaderOptionT[C, B] = ReaderOptionT { Reader { g(_) map f } }
def flatMap[B](f: R => ReaderOptionT[C, B]): ReaderOptionT[C, B] =
ReaderOptionT {
Reader { c =>
(g(c) map f) match {
case Some(r) => r.g(c)
case None => None
}
}
}
}
object ReaderOptionT {
def pure[C, R](value : => Option[R]): ReaderOptionT[C, R] =
ReaderOptionT { Reader { _ => value } }
implicit def toReaderOptionT[C, R](r : Reader[C, Option[R]]): ReaderOptionT[C, R] =
ReaderOptionT { r }
implicit def fromReaderOptionT[C, R](ropt : ReaderOptionT[C, R]): Reader[C, Option[R]] =
ropt.g
}
case class ReaderFutureT[C, R](g: Reader[C, Future[R]]) {
def map[B](f: R => B): ReaderFutureT[C, B] = ReaderFutureT { Reader { g(_) map f } }
def flatMap[B](f: R => ReaderFutureT[C, B]): ReaderFutureT[C, B] =
ReaderFutureT {
Reader { (c: C) => {
val p: Promise[B] = Promise()
val fut = g(c)
fut.onComplete {
case Success(x) => p.completeWith(f(x).g(c))
case Failure(t) => p.failure(t)
}
p.future
}
}
}
}
object ReaderFutureT {
def pure[C, R](value: => Future[R]): ReaderFutureT[C, R] =
ReaderFutureT { Reader { _ => value } }
implicit def toReaderFutureT[C, R](r: Reader[C, Future[R]]): ReaderFutureT[C, R] =
ReaderFutureT { r }
implicit def fromReaderFutureT[C, R](rft: ReaderFutureT[C, R]): Reader[C, Future[R]] =
rft.g
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment