我从OCaml得到以下错误,我不明白为什么。我试图在OCaml中定义一个解释器。我有一些类型和功能来评估这些类型。我粘贴相关代码。
我有以下类型:
type ide = string
type exp = Eint of int
| Ebool of bool
| Var of ide
| Prod of exp * exp
| Sum of exp * exp
| Diff of exp * exp
| Eq of exp * exp
| Minus of exp
| Iszero of exp
| Or of exp * exp
| And of exp * exp
| Not of exp
| Ifthenelse of exp * exp * exp
| Let of ide * exp * exp
| Fun of ide list * exp
| Funval of exp * exp env
| Appl of exp * exp list
| Dot of ide * field_name
|Field of ide * exp
| Record of ide * exp list;;
type 'a env = Env of (ide * 'a) list;;
我有一个用于评估exp的函数eval。它工作正常。
let rec eval ((e: exp), (r: exp env)) =
match e with
| Eint(n) -> Eint(n)
| Ebool(b) -> Ebool(b)
| Var(i) -> lookup r i
| Iszero(a) -> iszero(eval(a, r))
| Eq(a, b) -> equ(eval(a, r),eval(b, r))
| Prod(a, b) -> mult(eval(a, r), eval(b, r))
| Sum(a, b) -> plus(eval(a, r), eval(b, r))
| Diff(a, b) -> diff(eval(a, r), eval(b, r))
| Minus(a) -> minus(eval(a, r))
| And(a, b) -> et(eval(a, r), eval(b, r))
| Or(a, b) -> vel(eval(a, r), eval(b, r))
| Not(a) -> non(eval(a, r))
| Ifthenelse(a, b, c) -> let g = eval(a, r) in
if typecheck("bool", g) then
(if g = Ebool(true) then eval(b, r) else eval(c, r))
else failwith ("nonboolean guard")
| Let(i, e1, e2) ->
eval(e2, bind (r, i, eval(e1, r)))
| Fun(x, a) -> Funval(e, r)
| Appl(e1, e2) -> match eval(e1, r) with
| Funval(Fun(x, a), r1) ->
eval(a, bind_list r1 x e2)
| _ -> failwith("no funct in apply")
let eval_field (field:exp) (r: exp env)= match field with
| Field (id, e) -> Field (id, (eval e r))
| _ -> failwith ("Not a Field");;
最后我有一个评估记录字段的函数:
let eval_field (field:exp) (r: exp env)= match field with
| Field (id, e) -> Field (id, (eval e r))
| _ -> failwith ("Not a Field");;
问题在于eval_field:OCaml告诉我错误:
Characters 22-24:
let f1 = Field ("f1", e1);;
^^
Error: This expression has type exp/1542
but an expression was expected of type exp/2350
可能有什么不对? 非常感谢你的帮助。
答案 0 :(得分:2)
编译器试图告诉您,您有两种名为exp
的不同类型,并且您有一种类型,而另一种是预期的。
我在此代码中只看到exp
类型的一个定义。我怀疑你的环境不干净。您可以尝试在新的OCaml解释器中加载代码。或许问题在于你没有展示的一些代码。
这是一个显示错误产生方式的会话:
$ ocaml
OCaml version 4.02.1
# type abc = A | B | C;;
type abc = A | B | C
# let f (x: abc) = x = A;;
val f : abc -> bool = <fun>
# type abc = A | B | C;;
type abc = A | B | C
# f (C: abc);;
Error: This expression has type abc/1024
but an expression was expected of type abc/1018
我的猜测是你有一个函数(比如这里的f
)是使用exp
类型的旧定义定义的。但是你用一个新类型的定义来调用它(就像这里一样)。