Reputation: 127
I'm currently working on a homework assignment. Essentially it's a very basic version of symbolic math. The following snippet of code works perfectly fine.
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 ... *)
For example if I enter in "eval (Plus (Int 3) (Int 5)) []" it properly returns 8. However when I try to add a "let" expression it gives an error. Here is a snippet of my modified eval function:
(* 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" *)
I believe the reason is that the compiler sees the code as:
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 ... *)
If my intuition is right that this is the error, how do I fix it?
If there's another cause for my error, what is it?
Upvotes: 0
Views: 330
Reputation: 35210
you should either delimit your inner matches with parens (or their syntactic equivalents begin/end
), or to factor your code into separate helper functions. I definitely prefer the latter.
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 -> ...
Upvotes: 2