类型约束

最后要注意的一点是,签名也可以把类型约束为一个特定的接口(interface)。

// sort :: Ord a => [a] -> [a]

胖箭头左边表明的是这样一个事实:a 一定是个 Ord 对象。也就是说,a 必须要实现 Ord 接口。Ord 到底是什么?它是从哪来的?在一门强类型语言中,它可能就是一个自定义的接口,能够让不同的值排序。通过这种方式,我们不仅能够获取关于 a 的更多信息,了解 sort 函数具体要干什么,而且还能限制函数的作用范围。我们把这种接口声明叫做类型约束 (type constraints)。

// assertEqual :: (Eq a, Show a) => a -> a -> Assertion

这个例子中有两个约束:EqShow。它们保证了我们可以检查不同的 a 是否相等,并在有不相等的情况下打印出其中的差异。

我们将会在后面的章节中看到更多类型约束的例子,其含义也会更加清晰。