I'm learning OCaml from the MOOC offered by Université Paris Diderot. At the moment i have not encounter major struggle with functional thinking, but i do find this piece of code, a little bit ugly. How can i refactor it, so i can write general evaluation of e1, and e2 that serves for two latest branches of the match statement included in the simplify function. The idea of this function is to transform e * 0 or 0 * e into 0; e * 1 or 1 * e into e; and e + 0 or 0 + e into e.
type exp =
| EInt of int
| EAdd of exp * exp
| EMul of exp * exp;;
let eval expression =
let rec aux = function
| EInt x -> x
| EAdd (e1, e2) -> (aux e1) + (aux e2)
| EMul (e1, e2) -> (aux e1) * (aux e2)
in aux expression;;
let simplify expression =
match expression with
| EInt _ -> expression
| EAdd (e1, e2) ->
let v1 = eval e1 in
let v2 = eval e2 in
if v1 = 0 then e2
else if v2 = 0 then e1
else expression
| EMul (e1, e2) ->
let v1 = eval e1 in
let v2 = eval e2 in
if v1 = 0 || v2 = 0 then EInt 0
else if v1 = 1 then e2
else if v2 = 1 then e1
else expression;;
I appreciate you help! Thanks!
I guess you can have a function like this:
let simplifyop identity zero exp e1 e2 =
let v1 = eval e1 in
let v2 = eval e2 in
if v1 = identity then e2
else if v2 = identity then e1
else
match zero with
| None -> exp
| Some z ->
if v1 = z || v2 = z then EInt z
else exp
Then your cases look like this:
| EAdd (e1, e2) -> simplifyop 0 None expression e1 e2
| EMul (e1, e2) -> simplifyop 1 (Some 0) expression e1 e2