ocaml类型推断中的匿名变量
我是Ocaml新手,在为lambda演算编写解释器时遇到了一个奇怪的错误ocaml类型推断中的匿名变量,ocaml,type-inference,Ocaml,Type Inference,我是Ocaml新手,在为lambda演算编写解释器时遇到了一个奇怪的错误 let rec valof : exp -> env -> value = fun exp env -> match exp with Var n -> exp2value (lookup env n) | Lambda (name , body) -> Clos (name , body , env) (*some thing wrong here*)
let rec valof : exp -> env -> value =
fun exp env ->
match exp with
Var n -> exp2value (lookup env n)
| Lambda (name , body) -> Clos (name , body , env) (*some thing wrong here*)
| _ -> Err
;;
exp
、value
和env
的定义如下:
type exp =
Num of int
| Str of string
| Err
| Var of string
| Lambda of string * exp
| App of exp * exp
;;
type value =
Num of int
| Str of string
| Clos of string * exp * env
| Err
;;
type env =
Empty
| Cons of string * exp * env
;;
编译时,编译器在解释器的lambda行上抱怨:
Error: This expression has type env/1490
but an expression was expected of type env/1457
知道我哪里搞砸了吗?
谢谢
当您在交互式顶级(REPL)中调试代码时,这种错误非常常见,这意味着您声明了两次类型env
。如果您在REPL中复制粘贴代码,则可能会发生这种情况
您不需要附加所有这些
代码>在每条语句之后。OCaml编译器不需要它们。然而,由于〈代码〉代码>意味着它只在顶层有用,而且只在顶层有用
如您所知,在进行模式匹配或定义求和类型时,可以省略第一个|
。但是,由于您希望在任何情况下都保持对齐,因此通常认为在每一行上包含|
是一种良好的做法,即使这不是一项义务
这里的类型不是相互依赖的,而是取决于exp
和env
,并且取决于exp
,这意味着您必须按照正确的顺序仔细声明类型。但为了清楚起见,您可能希望以另一种更符合逻辑的顺序呈现它们。(我不是说这个顺序比另一个好,我只是想让你知道你可以使用下面的语法)
例如,如果要自上而下地显示类型(从图片对象(即环境)到内部对象(即值)),可以使用和语法,告诉编译器类型相互依赖
type env =
| Empty
| Cons of string * exp * env
and exp =
| Num of int
| Str of string
| Err
| Var of string
| Lambda of string * exp
| App of exp * exp
and value =
| Num of int
| Str of string
| Clos of string * exp * env
| Err
最后一件事,value
和exp
都包含以下构造函数numofint
和strofstring
,OCaml无法判断int1
应该是value
还是exp
。更准确地说,OCaml将选择构造函数Int
引用env
或exp
(它将选择的构造函数取决于声明它们的顺序)。因此,建议为构造函数选择不同的名称。这意味着env
在不同范围的不同行上声明了两次。这两种类型的名称相同,但不相等。(回答:-)我明天会找到一些合适的参考资料,然后写一个。
type env =
| Empty
| Cons of string * exp * env
and exp =
| Num of int
| Str of string
| Err
| Var of string
| Lambda of string * exp
| App of exp * exp
and value =
| Num of int
| Str of string
| Clos of string * exp * env
| Err