如何重构这个模式匹配OCaml代码片段

时间:2016-10-23 03:47:07

标签: functional-programming pattern-matching ocaml

我正在从UniversitéParisDiderot提供的MOOC学习OCaml。目前我还没有遇到过与功能性思维的重大斗争,但我确实发现这段代码,有点难看。我如何重构它,所以我可以编写e1的一般评估,e2用于简化函数中包含的匹配语句的两个最新分支。这个函数的想法是将e * 0或0 * e转换为0; e * 1或1 * e进入e;和e + 0或0 + e到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;;

感谢您的帮助! 谢谢!

1 个答案:

答案 0 :(得分: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