Skip to content

Instantly share code, notes, and snippets.

@b-studios
Created February 1, 2017 18:44
Show Gist options
  • Save b-studios/b96d6331adc9969236011b94195f2bae to your computer and use it in GitHub Desktop.
Save b-studios/b96d6331adc9969236011b94195f2bae to your computer and use it in GitHub Desktop.
Churchencoding of Cofree Terms
trait Expr[-I, +O] {
def Lit: Int => O
def Add: (I, I) => O
}
trait Term {
def apply[R](alg: Expr[R, R]): R
}
trait AnnotTerm[A] {
def apply[R](alg: Expr[R, A => R]): R
}
def annotate[A](t: Term, algA: Expr[A, A]): AnnotTerm[A] =
t.apply(new Expr[(A, AnnotTerm[A]), (A, AnnotTerm[A])] {
def Lit = n => {
val a = algA.Lit(n)
val t = new AnnotTerm[A] {
def apply[R](alg: Expr[R, A => R]) = alg.Lit(n)(a)
}
(a, t)
}
def Add = (lhs, rhs) => {
val a = algA.Add(lhs._1, rhs._1)
val t = new AnnotTerm[A] {
def apply[R](alg: Expr[R, A => R]) =
alg.Add(lhs._2(alg), rhs._2(alg))(a)
}
(a, t)
}
})._2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment