最后要注意的一点是,签名也可以把类型约束为一个特定的接口(interface)。
// sort :: Ord a => [a] -> [a]
胖箭头左边表明的是这样一个事实:a
一定是个 Ord
对象。也就是说,a
必须要实现 Ord
接口。Ord
到底是什么?它是从哪来的?在一门强类型语言中,它可能就是一个自定义的接口,能够让不同的值排序。通过这种方式,我们不仅能够获取关于 a
的更多信息,了解 sort
函数具体要干什么,而且还能限制函数的作用范围。我们把这种接口声明叫做类型约束 (type constraints)。
// assertEqual :: (Eq a, Show a) => a -> a -> Assertion
这个例子中有两个约束:Eq
和 Show
。它们保证了我们可以检查不同的 a
是否相等,并在有不相等的情况下打印出其中的差异。
我们将会在后面的章节中看到更多类型约束的例子,其含义也会更加清晰。