https://www.reddit.com/r/scala/comments/s6ih9p/comment/htagml4/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button
trait Expr[T] {
def num(n: Int): T
def add(l: T, r: T): T
}
implicit def eval: Expr[Int] = new Expr[Int] {
def num(i: Int): Int = i
def add(l: Int, r: Int): Int = l + r
}
implicit def show: Expr[String] = new Expr[String] {
def num(i: Int): String = i.toString
def add(l: String, r: String): String = l + "+" + r
}
def program[T](implicit expr: Expr[T]) = expr.add(expr.num(1), expr.num(2))
trait Expr[T[_]] {
def num(n: Int): T[Int]
def bool(b: Boolean): T[Boolean]
def add(l: T[Int], r: T[Int]): T[Int]
def eq(l: T[Int], r: T[Int]): T[Boolean]
}
type Id[T] = T
implicit def eval: Expr[Id] = new Expr[Id] {
def num(i: Int): Id[Int] = i
def bool(b: Boolean): Id[Boolean] = b
def add(l: Id[Int], r: Id[Int]): Id[Int] = l + r
def eq(l: Id[Int], r: Id[Int]): Id[Boolean] = l == r
}
def program[T[_]](implicit expr: Expr[T]) = expr.add(expr.num(1), expr.num(2))