F#中的Hindley Milner类型推断

时间:2011-12-06 07:29:16

标签: f# type-inference hindley-milner

在下面的F#程序中,有人可以解释一步一步的类型推断:

let rec sumList lst =
    match lst with
    | [] -> 0
    | hd :: tl -> hd + sumList tl

我特别希望逐步了解Hindley Milner的统一过程。

1 个答案:

答案 0 :(得分:16)

有趣的东西!

首先我们为sumList创建一个泛型类型: x -> y

得到简单的方程式: t(lst) = x; t(match ...) = y

现在添加等式: 因t(lst) = [a]

(match lst with [] ...)

然后是等式: b = t(0) = Int; y = b

因为0是匹配的可能结果: c = t(match lst with ...) = b

从第二种模式: t(lst) = [d]; t(hd) = e; t(tl) = f; f = [e]; t(lst) = t(tl); t(lst) = [t(hd)]

猜测hd的类型(通用类型): g = t(hd); e = g

然后我们需要一个sumList的类型,所以我们现在才会得到一个无意义的函数类型: h -> i = t(sumList)

现在我们知道了: h = f; t(sumList tl) = i

然后从添加中我们得到: Addable g; Addable i; g = i; t(hd + sumList tl) = g

现在我们可以开始统一了:

t(lst) = t(tl) => [a] = f = [e] => a = e

t(lst) = x = [a] = f = [e]; h = t(tl) = x

t(hd) = g = i /\ i = y => y = t(hd)

x = t(lst) = [t(hd)] /\ t(hd) = y => x = [y]

y = b = Int /\ x = [y] => x = [Int] => t(sumList) = [Int] -> Int

我跳过了一些微不足道的步骤,但我认为你可以了解它是如何运作的。