'a
和'_l
之间有什么区别?
我正在看这个错误,无法理解它:
Error: This expression has type ('a -> float polynomial) list but an expression was expected of type float polynomial list derivlist: ('_l → float polynomial) list
答案 0 :(得分:24)
_
表示一个弱多态变量:它处于无法推广的位置。
在OCaml FAQ中有两个与弱多态性相关的解释:见A function obtained through partial application is not polymorphic enough和下一个。
这通常发生在您使用非本地引用(其类型不能一般化)时,或者定义非语法功能的多态函数时(它们不以fun x -> ..
开头,而是函数应用程序) )。在某些情况下,有一个简单的修复(eta扩展,请参阅常见问题解答),有时没有,有时你的程序只是不健全。
一个简单的例子:let a = ref []
没有获得多态a list ref
类型。否则,您可以同时使用int list
和bool list
,并通过改变引用来混合不同类型的元素。它取而代之的是'_a list ref
类型。这意味着该类型不是多态的,而只是 unknown 。使用特定类型的a
执行某项操作后,它会一劳永逸地修复'_a
。
# let a = ref [];;
val a : '_a list ref = {contents = []}
# let sum_of_a = List.fold_left (+) 0 !a;;
val sum_of_a : int = 0
# a;;
- : int list ref = {contents = []}
有关值限制和OCaml类型检查器中实际实现的“宽松”值限制的深入解释,请参阅Jacques Garrigue撰写的Relaxing the Value Restriction论文(2004)。
答案 1 :(得分:1)
编译器的错误消息中有一个弱类型变量,但我不确定弱变量是否与错误有关(我不知道类型变量的状态如何可能是此消息的原因)。
您确定没有定义两种类型polynomial
吗?这就是他在FAQ(“Error message: a type is not compatible with itself”)答案中指出的两个问题。