sealed abstract class Expr[T]
case class IntExpr(value: Int) extends Expr[Int]
case class BooleanExpr(value: Boolean) extends Expr[Boolean]
case class IfExpr[A](cond: Expr[Boolean], then: Expr[A], otherwise: Expr[A]) extends Expr[A]
case class AddExpr(left: Expr[Int], right: Expr[Int]) extends Expr[Int]
object Main extends App {
def eval[A](expr: Expr[A]): A =
expr match {
case IntExpr(x) => x
case BooleanExpr(x) => x
case IfExpr(cond, then, otherwise) =>
eval(if (eval(cond)) then else otherwise)
case AddExpr(left, right) =>
eval(left) + eval(right)
}
println(eval(IfExpr(BooleanExpr(false), IntExpr(1), AddExpr(IntExpr(2), IntExpr(3)))))
}