2015-10-30 85 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這裏)。但是你用這個類型的新定義的值來調用它(如這裏所示)。