OCaml interpeter 错误,"eval FunCall R" 上的参数太多
OCaml interpeter error, too many argument on "eval FunCall R"
我正在用 OCaml 编写一个语言解释器。
使用 ApplyOver 我必须在类型字典的每个值上映射一个函数,它由 (ide * exp) -> ("key", value).
如果函数是字典上的"fun x-> x+1"("key1",Eint 2),("key2",Eint 3),那么ApplyOver会将+1加到2和+1到 3.
我在最后一行有这个错误,这个函数的类型是 exp -> evT env -> evT
它适用于太多的论点;也许你忘记了 `;'.
代码(没有标准评估):
type exp = ... | Dict of (ide * exp) list | ApplyOver of exp * exp;;
type evT = ... | DictVal of (ide * exp) list
let rec eval (e : exp) (r : evT env) : evT = match e with
Dict(pairs) ->
if invariant pairs then DictVal(evalDictList pairs r)
else failwith("The Dictionary has multiple copy of the same key")|
ApplyOver(ex, dict) ->
(match (eval dict r) with
DictVal(pairs) -> DictVal(applyover ex pairs)|
_-> failwith ("not a dictionary"))|
Estring s -> String s |
Eint n -> Int n |
Ebool b -> Bool b |
IsZero a -> iszero (eval a r) |
Den i -> applyenv r i |
Eq(a, b) -> eq (eval a r) (eval b r) |
Prod(a, b) -> prod (eval a r) (eval b r) |
Sum(a, b) -> sum (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 = Bool(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(i, a) -> FunVal(i, a, r) |
FunCall(f, eArg) ->
let fClosure = (eval f r) in
(match fClosure with
FunVal(arg, fBody, fDecEnv) ->
eval fBody (bind fDecEnv arg (eval eArg r)) |
RecFunVal(g, (arg, fBody, fDecEnv)) ->
let aVal = (eval eArg r) in
let rEnv = (bind fDecEnv g fClosure) in
let aEnv = (bind rEnv arg aVal) in
eval fBody aEnv |
_ -> failwith("non functional value")) |
Letrec(f, funDef, letBody) ->
(match funDef with
Fun(i, fBody) -> let r1 = (bind r f (RecFunVal(f, (i, fBody, r)))) in
eval letBody r1 |
_ -> failwith("non functional def"))
and evalDictList (pairs : (ide * exp) list) (r : evT env) : (ide * evT) list = match pairs with
[ ] -> [ ] |
(key,value) :: other -> (key, eval value r) :: evalDictList other r
and applyover (ex : exp) (listtoscan : (ide * evT) list) : (ide * evT) list = match listtoscan with
[ ] -> [ ] |
(key,value) :: other -> (key, eval FunCall(ex, value) r) :: applyover ex other;;
函数应用程序的优先级仅次于方法调用(和类似的用户定义运算符)。因此编译器将 eval FunCall(ex, value) r
读作
(eval FunCall) (ex, value) r
当你打算写的时候
eval (Funcall(ex,value)) r
我正在用 OCaml 编写一个语言解释器。
使用 ApplyOver 我必须在类型字典的每个值上映射一个函数,它由 (ide * exp) -> ("key", value).
如果函数是字典上的"fun x-> x+1"("key1",Eint 2),("key2",Eint 3),那么ApplyOver会将+1加到2和+1到 3.
我在最后一行有这个错误,这个函数的类型是 exp -> evT env -> evT 它适用于太多的论点;也许你忘记了 `;'.
代码(没有标准评估):
type exp = ... | Dict of (ide * exp) list | ApplyOver of exp * exp;;
type evT = ... | DictVal of (ide * exp) list
let rec eval (e : exp) (r : evT env) : evT = match e with
Dict(pairs) ->
if invariant pairs then DictVal(evalDictList pairs r)
else failwith("The Dictionary has multiple copy of the same key")|
ApplyOver(ex, dict) ->
(match (eval dict r) with
DictVal(pairs) -> DictVal(applyover ex pairs)|
_-> failwith ("not a dictionary"))|
Estring s -> String s |
Eint n -> Int n |
Ebool b -> Bool b |
IsZero a -> iszero (eval a r) |
Den i -> applyenv r i |
Eq(a, b) -> eq (eval a r) (eval b r) |
Prod(a, b) -> prod (eval a r) (eval b r) |
Sum(a, b) -> sum (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 = Bool(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(i, a) -> FunVal(i, a, r) |
FunCall(f, eArg) ->
let fClosure = (eval f r) in
(match fClosure with
FunVal(arg, fBody, fDecEnv) ->
eval fBody (bind fDecEnv arg (eval eArg r)) |
RecFunVal(g, (arg, fBody, fDecEnv)) ->
let aVal = (eval eArg r) in
let rEnv = (bind fDecEnv g fClosure) in
let aEnv = (bind rEnv arg aVal) in
eval fBody aEnv |
_ -> failwith("non functional value")) |
Letrec(f, funDef, letBody) ->
(match funDef with
Fun(i, fBody) -> let r1 = (bind r f (RecFunVal(f, (i, fBody, r)))) in
eval letBody r1 |
_ -> failwith("non functional def"))
and evalDictList (pairs : (ide * exp) list) (r : evT env) : (ide * evT) list = match pairs with
[ ] -> [ ] |
(key,value) :: other -> (key, eval value r) :: evalDictList other r
and applyover (ex : exp) (listtoscan : (ide * evT) list) : (ide * evT) list = match listtoscan with
[ ] -> [ ] |
(key,value) :: other -> (key, eval FunCall(ex, value) r) :: applyover ex other;;
函数应用程序的优先级仅次于方法调用(和类似的用户定义运算符)。因此编译器将 eval FunCall(ex, value) r
读作
(eval FunCall) (ex, value) r
当你打算写的时候
eval (Funcall(ex,value)) r