Skip to content

Instantly share code, notes, and snippets.

@einblicker
Created November 4, 2011 06:14
Show Gist options
  • Save einblicker/1338773 to your computer and use it in GitHub Desktop.
Save einblicker/1338773 to your computer and use it in GitHub Desktop.
scalaz and reify/reflect
import util.continuations._
import scalaz._
import Scalaz._
def reify[M[_] : Monad, A](body: => A @cps[M[A]]): M[A] =
reset{val result: A = body; implicitly[Monad[M]].pure[A](result)}
implicit def monad2reflect[M[_] : Monad, A](action: M[A]) = new {
def reflect[B]: A @cps[M[B]] =
shift{(k: A => M[B]) => implicitly[Monad[M]].bind(action, k)}
}
def guard[M[_], A](x: Boolean)(
implicit m: Monad[M], z: Zero[M[Unit]]
): Unit @cps[M[A]] =
if (x) m.pure[Unit](()).reflect[A] else z.zero.reflect[A]
//example
reify {
type Result = Seq[Int]
val nums = 0 to 9 toStream
val nums1 = 1 to 9 toStream
val S = nums1.reflect[Result]
val E = nums.filterNot(S ==).reflect[Result]
val N = nums.filterNot(Seq(S, E).contains).reflect[Result]
val D = nums.filterNot(Seq(S, E, N).contains).reflect[Result]
val M = nums1.filterNot(Seq(S, E, N, D).contains).reflect[Result]
val O = nums.filterNot(Seq(S, E, N, D, M).contains).reflect[Result]
val R = nums.filterNot(Seq(S, E, N, D, M, O).contains).reflect[Result]
val Y = nums.filterNot(Seq(S, E, N, D, M, O, R).contains).reflect[Result]
def toNum(nums: Seq[Int]) = nums.foldLeft(0)(_*10+_)
guard[Stream, Result] {
toNum(Seq(S, E, N, D)) + toNum(Seq(M, O, R, E)) ==
toNum(Seq(M, O, N, E, Y))
}
Seq(S, E, N, D, M, O, R, E, M, O, N, E, Y)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment