LitExpr = Class {.i = Int} LitExpr. new i = Self::__new__ {.i;} LitExpr|<: Show|. show self = "{self.i}" AddExpr = Class {.lhs = Expr, .rhs = Expr} AddExpr. new lhs, rhs = Self::__new__ {.lhs; .rhs} AddExpr|<: Show|. show self = "{self.lhs} + {self.rhs}" SubExpr = Class {.lhs = Expr, .rhs = Expr} SubExpr. new lhs, rhs = Self::__new__ {.lhs; .rhs} SubExpr|<: Show|. show self = "{self.lhs} - {self.rhs}" PosExpr = Class {.expr = Expr} PosExpr. new expr = Self::__new__ {.expr;} PosExpr|<: Show|. show self = "+{self.expr}" NegExpr = Class {.expr = Expr} NegExpr. new expr = Self::__new__ {.expr;} NegExpr|<: Show|. show self = "-{self.expr}" Expr = Enum LitExpr: AddExpr SubExpr NegExpr Expr. lit = LitExpr.new |> Self.new add = AddExpr.new |> Self.new 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