2016-10-23 40 views
0

我正在从UniversitéParis Diderot提供的MOOC中学习OCaml。目前我还没有遇到与功能思维的重大斗争,但我确实发现了这段代码,有点难看。我如何重构它,所以我可以编写对e1和e2的一般性评估,并为简化函数中包含的匹配语句的两个最新分支提供服务。这个函数的思想是将e * 0或0 * e转换为0; e * 1或1 * e到e;和e + 0或0 + e变成e。如何重构这种模式匹配OCaml代码片

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;; 

我感谢您的帮助! 谢谢!

回答

1

我想你可以有这样的功能:

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 

然后你的情况是这样的:

| EAdd (e1, e2) -> simplifyop 0 None expression e1 e2 
| EMul (e1, e2) -> simplifyop 1 (Some 0) expression e1 e2