2016-10-23 39 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