Skip to content

Instantly share code, notes, and snippets.

@leque
Created July 1, 2012 05:12
Show Gist options
  • Save leque/3026911 to your computer and use it in GitHub Desktop.
Save leque/3026911 to your computer and use it in GitHub Desktop.
Direct-Style Monads
trait Monad[M[_]] {
def unit[A](x : A) : M[A]
def bind[A, B](m : M[A], f : A => M[B]) : M[B]
}
implicit object OptionMonad extends Monad[Option] {
def unit[A](x : A) = Some(x)
def bind[A, B](m : Option[A], f : A => Option[B]) = m.flatMap(f)
}
implicit object ListMonad extends Monad[List] {
def unit[A](x : A) = List(x)
def bind[A, B](m : List[A], f : A => List[B]) = m.flatMap(f)
}
import scala.util.continuations._
def reify[A, M[+_]](x : => A @cpsParam[M[A], M[A]])(implicit monad : Monad[M]) : M[A] =
reset { monad.unit(x) }
class Reflective[+A, M[_]](m : M[A], monad : Monad[M]) {
def reflect[B]() : A @cpsParam[M[B], M[B]] = {
shift { (k : A => M[B]) =>
monad.bind(m, k)
}
}
}
implicit def reflective[A](xs : Option[A])(implicit monad : Monad[Option]) =
new Reflective[A, Option](xs, monad)
implicit def reflective[A](xs : List[A])(implicit monad : Monad[List]) =
new Reflective[A, List](xs, monad)
reify {
val left = List("x", "y", "z").reflect[(String, Int)]
val right = List(4, 5, 6).reflect[(String, Int)]
(left, right)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment