3

我正在使用 Learn You a Haskell 来学习 Haskell。在第 54 页是 take 的实现,如下所示:

take' :: (Num i, Ord i) => i -> [a] -> [a]
take' n _
    | n <= 0 = []
take' _ []   = []
take' n (x:xs) = x : take' (n-1) xs

我理解除第一行之外的所有代码。

我理解的 :: 部分意味着这是一个类型定义?

(Num i, Ord i) 是一个元组。元组的第一个元素必须是数字,足够公平。第二个参数必须能够被订购。参数是相同的 - 都是 i。这意味着类型必须相同?

为什么不是 (Num i, Ord j)?第二个元组元素不是指列表吗?哪个可以是任何类型?

=> 表示什么?

i -> [a] -> [a] 表示第一个参数是数字?第二个参数是任何类型列表,第三个参数是任何类型列表。所以这是说第一个参数是数字,第二个参数是任何类型的列表,它返回任何类型的列表。好吧,我想这是可以理解的。

4

2 回答 2

12

之前的东西=>约束(Num i, Ord i)不是通常意义上的元组。它指定了类型类实例存在于i您调用函数的任何特定类型的要求。

所以这个类型签名实际上是在说 is 的类型take',但是必须有和实例i -> [a] -> [a]的额外限制,这相当于要求你可以做一些基本的算术(我想是“数字”的缩写)并比较哪个值更大(意味着该类型的值已定义排序,即您可以对它们进行排序等)。iNumOrdNumOrd

在这种特殊情况下,比较n <= 0是使用Ord,而减法和数字文字使用Num

这在LYAH 的第 3 章中有介绍,这些特定的类型类(以及其他)在Typeclasses 101 部分中提到。

于 2013-04-10T13:23:22.887 回答
2

(Num i, Ord i) 并不意味着是一个元组。将类型签名读取为: take' 是类型的函数,i -> [a] -> [a]其中 i 必须是类型类 Num 和 Ord 的类型。

您可能想再次阅读“Typeclasses 101”一章。

于 2013-04-10T13:21:54.327 回答