LitExpr = Class {.i = Int}, Impl := Show LitExpr. new i = Self::__new__ {.i;} show self = "{self.i}" AddExpr = Class {.lhs = Expr, .rhs = Expr}, Impl := Show AddExpr. new lhs, rhs = Self::__new__ {.lhs; .rhs} show self = "{self.lhs} + {self.rhs}" SubExpr = Class {.lhs = Expr, .rhs = Expr}, Impl := Show SubExpr. new lhs, rhs = Self::__new__ {.lhs; .rhs} show self = "{self.lhs} - {self.rhs}" PosExpr = Class {.expr = Expr}, Impl := Show PosExpr. new expr = Self::__new__ {.expr;} show self = "+{self.expr}" NegExpr = Class {.expr = Expr}, Impl := Show NegExpr. new expr = Self::__new__ {.expr;} show self = "-{self.expr}" Expr = Enum LitExpr: AddExpr SubExpr NegExpr Expr. lit = Self.cons(LitExpr) add = Self.cons(AddExpr) eval self = match self: (l: Expr.LitExpr) -> l.i (a: Expr.AddExpr) -> a.lhs + a.rhs (s: Expr.SubExpr) -> s.lhs - s.rhs (p: Expr.PosExpr) -> p.expr (n: Expr.NegExpr) -> -n.expr expr = Expr.add Expr.lit(1), Expr.lit(2) print! expr # 1 + 2 assert expr.eval() == 3