2016-10-23 3 views
0

Я изучаю OCaml от MOOC, предлагаемого Université Paris Diderot. На данный момент я не сталкиваюсь с серьезной борьбой с функциональным мышлением, но я нахожу этот фрагмент кода, немного уродлив. Как я могу его реорганизовать, поэтому я могу написать общую оценку 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