了解take函数的类型签名

时间:2014-01-23 18:37:49

标签: haskell

take' :: (Num i, Ord i) => i -> [a] -> [a] 

(Num i , Ord i)表示类约束

i -> [a]表示这两个属于类约束

last [a]表示输出。

是正确的吗?

3 个答案:

答案 0 :(得分:4)

要理解你的要求有点困难。如果您只想知道类型签名的含义,可以将其分解为:

take' :: (Num i, Ord i) => i -> [a] -> [a]
-- ^--- The function named "take'"
take' :: (Num i, Ord i) => i -> [a] -> [a]
--    ^--- Has type
take' :: (Num i, Ord i) => i -> [a] -> [a]
--        ^--- Constrained where "i" implements "Num" and "Ord"
take' :: (Num i, Ord i) => i -> [a] -> [a]
--                         ^--- The first argument has type "i"
take' :: (Num i, Ord i) => i -> [a] -> [a]
--                              ^--- The second argument has type "[a]"
take' :: (Num i, Ord i) => i -> [a] -> [a]
--  The return value has type "[a]" ---^

所以在一个句子中,函数take'有两个参数,第一个参数必须是NumOrd,第二个参数必须是任何类型的列表,并且返回值与第二个参数的类型相同。

答案 1 :(得分:1)

在不知道实现的情况下,我只能评论类型签名。

你正确的约束部分。这是一种类型类约束,其中i必须具有NumOrd实例。

(Num i , Ord i) =>

第二部分是两个变量的函数,从有序数值ia的多态类型列表到相同类型a的列表。

i -> [a] -> [a]

此功能的实现可能如下所示:

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

答案 2 :(得分:0)

(Num i, Ord i)表示函数i的类型签名中的任何位置都是Num类和Ord类的成员。显然,这些数字和顺序都很短。这是他们的定义。

class Num a where
   (+), (*), (-) :: a -> a -> a
   negate :: a -> a
   abs :: a -> a
   signum :: a -> a
   fromInteger :: Integer -> a

class Eq a => Ord a where
   compare :: a -> a -> Ordering
   (<) :: a -> a -> Bool
   (>=) :: a -> a -> Bool
   (>) :: a -> a -> Bool
   (<=) :: a -> a -> Bool
   max :: a -> a -> a
   min :: a -> a -> a

那么这一切意味着什么呢。嗯,这意味着对于作为此类实例的每个类型,以下函数可以与该类型一起使用。对于Num类,这些是您希望能够应用于数字的基本操作。注意缺乏分裂。因为IntIntegerNum的一种类型,所以没有除法,因为如果你除以不可分割的东西,那么你最终会得到一个非整数类型。这就是为什么有更多类型类来处理这个问题,例如Fractional

Ord类提供了对某些类型的值进行排序的函数。这允许人们比较值并形成某种逻辑的值排序。

虽然我认为选择的类型签名有点奇怪

take' :: Integral i => i -> [a] -> [a]

会更有意义。