Сейчас я работаю над домашним заданием. По сути, это очень простая версия символической математики. Следующий фрагмент кода отлично работает.
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. Однако, когда я пытаюсь добавить выражение «let», оно выдает ошибку. Вот фрагмент моей модифицированной функции 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 ... *)
Если моя интуиция верна, что это ошибка, как мне ее исправить?
Если есть другая причина моей ошибки, в чем она?