Types OCaml类型系统的微妙之处:多态性、无点反转和嵌套列表

Types OCaml类型系统的微妙之处:多态性、无点反转和嵌套列表,types,functional-programming,polymorphism,ocaml,Types,Functional Programming,Polymorphism,Ocaml,如果我定义一个反向函数,比如: let reverse = let rec helper out = function | [] -> out | a :: l -> helper (a :: out) l in helper [] 然后reverse(List.map reverse xs)不进行类型检查,出现错误 Error: This expression has type 'a list list but an expression was e

如果我定义一个反向函数,比如:

let reverse =
  let rec helper out = function
    | [] -> out
    | a :: l -> helper (a :: out) l
  in helper []
然后
reverse(List.map reverse xs)
不进行类型检查,出现错误

Error: This expression has type 'a list list
   but an expression was expected of type 'a list
   The type variable 'a occurs inside 'a list
但是用一个明确的论点来定义它

let reverse l =
  let rec helper out = function
    | [] -> out
    | a :: l -> helper (a :: out) l
  in helper [] l
让事情顺利进行


这是怎么回事?

您最初的定义:

# let reverse =
    let rec helper out = function
      | [] -> out
      | a :: l -> helper (a :: out) l
      in helper [];;
val reverse : '_a list -> '_a list = <fun>
#让我们倒过来=
let rec helper out=函数
|[]->输出
|a::l->helper(a::out)l
在helper[];;
val reverse:“\u a list->”\u a list=
受到半著名的值限制,因为它的形式是应用程序(即,
helper[]
)而不是lambda

第二个定义的形式为lambda,不受值限制

其他一切都是如此

关于堆栈溢出的值限制已经讨论过多次。这里有一个这样的讨论:。简短的总结是,在存在可变值(如引用)的情况下,需要对使类型多态进行某种限制。价值限制是一种很容易记住的折衷方法,不需要太多限制

当我开始忘记价值限制是关于什么的时候(周期性地发生),我经常提到这篇文章: