Skip to content

Instantly share code, notes, and snippets.

@vsuharnikov
Created May 30, 2017 03:48
Show Gist options
  • Save vsuharnikov/d147a85ad5047137a2abedd385cff697 to your computer and use it in GitHub Desktop.
Save vsuharnikov/d147a85ad5047137a2abedd385cff697 to your computer and use it in GitHub Desktop.
Finally tagless example
trait Lit[T] {
def lit(x: Int): T
}
trait Add[T] {
def add(x: T, y: T): T
}
trait Mul[T] {
def mul(x: T, y: T): T
}
trait Eval {
val eval: Int
}
implicit val litEval = new Lit[Eval] {
override def lit(x: Int) = new Eval {
override val eval: Int = x
}
}
implicit val addEval = new Add[Eval] {
override def add(x: Eval, y: Eval) = new Eval {
override val eval: Int = x.eval + y.eval
}
}
implicit val mulEval = new Mul[Eval] {
override def mul(x: Eval, y: Eval) = new Eval {
override val eval: Int = x.eval * y.eval
}
}
trait View {
val view: String
}
implicit val litView = new Lit[View] {
override def lit(x: Int): View = new View {
override val view: String = x.toString
}
}
implicit val addView = new Add[View] {
override def add(x: View, y: View): View = new View {
override val view: String = s"${x.view} + ${y.view}"
}
}
implicit val mulView = new Mul[View] {
override def mul(x: View, y: View): View = new View {
override val view: String = s"(${x.view}) * (${y.view})"
}
}
def myExpr[T](implicit lit: Lit[T], add: Add[T], mul: Mul[T]): T = {
mul.mul(
lit.lit(5),
add.add(
lit.lit(10),
lit.lit(20)
)
)
}
myExpr[Eval].eval
myExpr[View].view
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment