OCaml中重叠的匹配语句

时间:2015-02-17 00:57:51

标签: ocaml

我目前正在做家庭作业。从本质上讲,它是符号数学的一个非常基本的版本。以下代码片段完美无缺。

let rec eval exp (vars:(string * int) list) = match exp with
    | Int n -> n
    | Plus (a, b) -> (eval a vars) + (eval b vars)
    (* ... more match statements ... *)

例如,如果我输入" eval(Plus(Int 3)(Int 5))[]"它正确返回8.然而,当我尝试添加"让"表达它给出了一个错误。这是我修改的eval函数的片段:

(* either returns Some value or None *)
let rec findVar key l = ...

let rec eval exp (vars:(string * int) list) = match exp with
    | Id id -> match (findVar id vars) with
        | Some value -> value
        | None -> raise (Failure ("Unknown variable " ^ id))
    | Int n -> n
    | Plus (a, b) -> (eval a vars) + (eval b vars)
    (* ... more match statements ... *)

(* raises "Error: The variant type option has no constructor Int" *)

我认为原因是编译器将代码视为:

let rec eval exp (vars:(string * int) list) = match exp with
    | Id id -> match (findVar id vars) with
        | Some value -> value
        | None -> raise (Failure ("Unknown variable " ^ id))
        | Int n -> n
        | Plus (a, b) -> (eval a vars) + (eval b vars)
        (* ... more match statements ... *)

如果我的直觉是对的,这就是错误,我该如何解决?

如果我的错误的另一个原因是什么?

1 个答案:

答案 0 :(得分:2)

你应该用parens(或它们的句法等价物begin/end)来区分你的内部匹配,或者将你的代码分解为单独的帮助函数。我当然更喜欢后者。

let rec eval exp (vars : (string * int) list) = match exp with
    | Id id -> eval_var vars id
    | Int n -> n
    | Plus (a, b) -> (eval a vars) + (eval b vars)
    (* ... more match statements ... *)
 and eval_var vars id = match findVar id vars with
    | Some v -> ...