如果你看一下OCaml中List.fold_left的类型,它会给出类型('a - >'b - >'a) - > 'a - > 'b list - > “一
我不确定如何完全理解这一点,我可以达到类似的类型,但我如何逐步进入最终类型?
答案 0 :(得分:3)
编译器使用基于众所周知的Hindley-Milner类型推断算法的类型推断算法。
从实现中推断出类型,例如,这是fold_left
函数的可能实现:
let rec fold_left f accu l =
match l with
[] -> accu
| a::l -> fold_left f (f accu a) l
一开始,所有值都具有最不受限制的类型。我们在此处有三个值:f
,accu
和l
。因此,它会分配类型变量'a
,'b
和'c
。类型变量'a
基本上意味着值可以是任何类型(完全不受约束)。
然后,typechecker会通过一个程序(它的AST表示)并收集有关如何使用每个值的事实。它使用syntactic unification算法来统一所有事实。例如,它看到l
与之匹配
一个列表,现在它推断,l
不仅是任何类型'c
的值,而且实际上被限制为'd list
。然后,类型检查器发现值f
应用于accu
和列表的元素(类型为'd
)。这意味着,f
不仅是'a
类型的值,而且是类型'b -> 'd -> 'b
的函数。所以,最后我们输入('b -> 'd -> 'b) -> 'b -> 'd list -> 'b
,然后将其重新规范化为('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
。我希望你有一个大致的想法,可以从链接的维基百科文章中获取细节:)