type expr = | Num of int | Add of expr * expr | Mul of expr * expr let rec simp e = match e with | Num n -> Num n | Add (a, b) -> (match (simp a, simp b) with | (Num 0, x) -> x | (x, Num 0) -> x | (Num n, Num m) -> Num (n + m) | (a', b') -> Add (a', b')) | Mul (a, b) -> (match (simp a, simp b) with | (Num 0, _) -> Num 0 | (_, Num 0) -> Num 0 | (Num 1, x) -> x | (x, Num 1) -> x | (Num n, Num m) -> Num (n * m) | (a', b') -> Mul (a', b')) let rec eval e = match e with | Num n -> n | Add (a, b) -> eval a + eval b | Mul (a, b) -> eval a * eval b ;; let e = Add (Mul (Num 3, Num 5), Add (Num 0, Mul (Num 1, Num 7))) in eval (simp e)