(module m (data Expr (ctor Lit (con Int)) (ctor Add (con Expr) (con Expr)) (ctor Mul (con Expr) (con Expr))) (fn eval (type (fn-type (params (own (con Expr))) (ret (own (con Int))))) (params e) (body (match e (case (pat-ctor Lit n) n) (case (pat-ctor Add a b) (app + (app eval a) (app eval b))) (case (pat-ctor Mul a b) (app * (app eval a) (app eval b)))))) (fn main (type (fn-type (params) (ret (own (con Unit))) (effects IO))) (params) (body (let e (term-ctor Expr Mul (term-ctor Expr Add (term-ctor Expr Lit 2) (term-ctor Expr Lit 3)) (term-ctor Expr Lit 4)) (seq (app print (app eval e)) (do io/print_str "\n"))))))