我目前正在做家庭作业。从本质上讲,它是符号数学的一个非常基本的版本。以下代码片段完美无缺。
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 ... *)
如果我的直觉是对的,这就是错误,我该如何解决?
如果我的错误的另一个原因是什么?
答案 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 -> ...