ocaml类型推断中的匿名变量

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*)

我是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*)
    |   _ -> 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