Created
April 11, 2017 16:59
-
-
Save weihsiu/8e266223a8199e9651d281db306ea7fb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package matryoshkasandbox | |
import matryoshka._ | |
import matryoshka.data._ | |
import matryoshka.implicits._ | |
import scalaz.Functor | |
object Exprs extends App { | |
sealed trait Expr[A] | |
case class Num[A](value: Int) extends Expr[A] | |
case class Add[A](left: A, right: A) extends Expr[A] | |
case class Sub[A](left: A, right: A) extends Expr[A] | |
case class Mul[A](left: A, right: A) extends Expr[A] | |
implicit val exprFunctor: Functor[Expr] = new Functor[Expr] { | |
def map[A, B](e: Expr[A])(f: A => B): Expr[B] = e match { | |
case Num(x) => Num(x) | |
case Add(x, y) => Add(f(x), f(y)) | |
case Sub(x, y) => Sub(f(x), f(y)) | |
case Mul(x, y) => Mul(f(x), f(y)) | |
} | |
} | |
val intEval: Algebra[Expr, Int] = { | |
case Num(x) => x | |
case Add(x, y) => x + y | |
case Sub(x, y) => x - y | |
case Mul(x, y) => x * y | |
} | |
val strEval: Algebra[Expr, String] = { | |
case Num(x) => x.toString | |
case Add(x, y) => s"($x + $y)" | |
case Sub(x, y) => s"($x - $y)" | |
case Mul(x, y) => s"($x * $y)" | |
} | |
val expr1: Fix[Expr] = | |
Fix(Mul( | |
Fix(Add( | |
Fix(Num(1)), | |
Fix(Num(2)) | |
)), | |
Fix(Sub( | |
Fix(Num(3)), | |
Fix(Num(4)) | |
)) | |
)) | |
val expr2: Fix[Expr] = | |
Mul( | |
Add( | |
Num[Fix[Expr]](1).embed, | |
Num[Fix[Expr]](2).embed | |
).embed, | |
Sub( | |
Num[Fix[Expr]](3).embed, | |
Num[Fix[Expr]](4).embed | |
).embed | |
).embed | |
val expr3: Mu[Expr] = | |
Mul( | |
Add( | |
Num[Mu[Expr]](1).embed, | |
Num[Mu[Expr]](2).embed | |
).embed, | |
Sub( | |
Num[Mu[Expr]](3).embed, | |
Num[Mu[Expr]](4).embed | |
).embed | |
).embed | |
def expr4[T](implicit ev: Corecursive.Aux[T, Expr]): T = | |
Mul( | |
Add( | |
Num[T](1).embed, | |
Num[T](2).embed | |
).embed, | |
Sub( | |
Num[T](3).embed, | |
Num[T](4).embed | |
).embed | |
).embed | |
println(expr1.cata(intEval)) | |
println(expr2.cata(strEval)) | |
println(expr3.cata(strEval)) | |
println(expr4[Mu[Expr]].cata(strEval)) | |
println(expr4[Fix[Expr]].cata(strEval)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment