JBolton
JBolton

Reputation: 127

Overlapping match statements in OCaml

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

Answers (1)

ivg
ivg

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

Related Questions