type Expr = | Num(Int) | Add(Expr, Expr) | Sub(Expr, Expr) | Mul(Expr, Expr) fn eval(e: Expr): Int = match e { Num(n) => n, Add(a, b) => eval(a) + eval(b), Sub(a, b) => eval(a) - eval(b), Mul(a, b) => eval(a) * eval(b), } fn showExpr(e: Expr): String = match e { Num(n) => toString(n), Add(a, b) => "(" + showExpr(a) + " + " + showExpr(b) + ")", Sub(a, b) => "(" + showExpr(a) + " - " + showExpr(b) + ")", Mul(a, b) => "(" + showExpr(a) + " * " + showExpr(b) + ")", } fn evalAndPrint(e: Expr): Unit with {Console} = { Console.print("Evaluating: " + showExpr(e)) Console.print("Result: " + toString(eval(e))) } fn main(): Unit with {Console} = { let e1 = Add(Num(2), Num(3)) evalAndPrint(e1) let e2 = Mul(Add(Num(1), Num(2)), Add(Num(3), Num(4))) evalAndPrint(e2) let e3 = Sub(Num(10), Mul(Num(2), Num(3))) evalAndPrint(e3) } let output = run main() with {}