缩小可能性范围

一旦引入一个类型变量,就会出现一个奇怪的特性叫做 parametricityhttp://en.wikipedia.org/wiki/Parametricity )。这个特性表明,函数将会以一种统一的行为作用于所有的类型。我们来研究下:

  1. // head :: [a] -> a

注意看 head,可以看到它接受 [a] 返回 a。我们除了知道参数是个数组,其他的一概不知;所以函数的功能就只限于操作这个数组上。在它对 a 一无所知的情况下,它可能对 a 做什么操作呢?换句话说,a 告诉我们它不是一个特定的类型,这意味着它可以是任意类型;那么我们的函数对每一个可能的类型的操作都必须保持统一。这就是 parametricity 的含义。要让我们来猜测 head 的实现的话,唯一合理的推断就是它返回数组的第一个,或者最后一个,或者某个随机的元素;当然,head 这个命名应该能给我们一些线索。

再看一个例子:

  1. // reverse :: [a] -> [a]

仅从类型签名来看,reverse 可能的目的是什么?再次强调,它不能对 a 做任何特定的事情。它不能把 a 变成另一个类型,或者引入一个 b;这都是不可能的。那它可以排序么?答案是不能,没有足够的信息让它去为每一个可能的类型排序。它能重新排列么?可以的,我觉得它可以,但它必须以一种可预料的方式达成目标。另外,它也有可能删除或者重复某一个元素。重点是,不管在哪种情况下,类型 a 的多态性(polymorphism)都会大幅缩小 reverse 函数可能的行为的范围。

这种“可能性范围的缩小”(narrowing of possibility)允许我们利用类似 Hoogle 这样的类型签名搜索引擎去搜索我们想要的函数。类型签名所能包含的信息量真的非常大。