Skip to content

Instantly share code, notes, and snippets.

@weihsiu
Created April 11, 2017 16:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weihsiu/8e266223a8199e9651d281db306ea7fb to your computer and use it in GitHub Desktop.
Save weihsiu/8e266223a8199e9651d281db306ea7fb to your computer and use it in GitHub Desktop.
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