2015-10-30 86 views
0

从OCaml我有以下错误,我不明白为什么。我试图在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;; 

我用的eval 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

在Ocaml中,大多数情况下你不需要给出像field这样的对象的类型:exp,他是为你做的。类型exp被定义两次。 –

+0

(对于它的价值,这对我来说看起来不太合适,或者至少我在这里只能看到'exp'的一个定义,而且它可以是有用的文档来标记函数参数的类型。) –

+0

'eval_field '不包含那条线。它看起来更像是你在口译员中交互式输入的。 – molbdnilo

回答

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 

我的猜测是,你有一个使用您的exp类型的旧的定义定义的函数(如f这里)。但是你用这个类型的新定义的值来调用它(如这里所示)。