[英]Haskell Type Signatures
I am new to haskell and I read some stuff about this thing called type signatures, but there are a few things that I dont understand. 我是haskell的新手,我读了一些关于这个称为类型签名的东西,但有一些我不理解的东西。
Here is the the code am looking at: 这是我正在看的代码:
--mult applies product
mult :: Num a => [a] -> a
mult = foldr (*) 1
--posList filters positive numbers out
posList :: (Ord a, Num a) => [a] -> [a]
posList = filter (>0)
--trueList determines whether all of the members of a list are T or not
trueList :: [Bool] -> Bool
trueList = foldr(&&) True
--evenList determines where all of the members of a list are even or not
evenList :: (Integral a, Foldable t) => t a -> Bool
evenList x = if (((foldr (+) 2 x ) `mod` 2) == 0) then True else False
So, I know you can do those functions easier in a different way, but I had assignments to use higher order functions map
, filter
and foldr
, so I had to do them that way. 所以,我知道你可以用不同的方式更容易地完成这些功能,但我有使用更高阶函数map
, filter
和foldr
赋值,所以我必须这样做。 Anyway, I understand how the functions work since I am the one who wrote them , what I dont understand is those terms Integral
, Foldable
, what do they mean? 无论如何,我理解这些功能是如何工作的,因为我是编写它们的人,我不理解的是那些术语Integral
, Foldable
,它们是什么意思? and what are they called in terms of Haskell? 他们用Haskell称之为什么?
Those are constraints to a polymorphic type . 这些是多态类型的约束 。
Haskell, despite being statically typed, makes it very easy to write function that can work with different types, through a system called parametric polymorphism . Haskell尽管是静态类型的,但通过称为参数多态的系统,可以很容易地编写可以使用不同类型的函数。 I'll first give all your functions concrete (monomorphic) signatures instead: 我将首先为您的所有函数提供具体(单态)签名:
mult :: [Integer] -> Integer
mult = foldl' (*) 1 -- foldl' is better for performance/memory than foldr
posList :: [Integer] -> [Integer]
posList = filter (>0)
trueList :: [Bool] -> Bool
trueList = foldl' (&&) True
evenList :: [Integer] -> Bool
evenList x = foldl' (+) 2 x `mod` 2 == 0
-- `if True then True else False` is tautological
All of these signatures work (both with the improved implementation and with your original ones). 所有这些签名都有效(包括改进的实现和原始的签名)。
But they only work with lists of Integer
. 但它们只适用于Integer
列表。 That's not always sufficiently general; 这并不总是足够笼统; for instance, it's perfectly reasonable to compute the product of a list of fractional numbers. 例如,计算分数列表的乘积是完全合理的。 But with the monomorphic signature, mult [1.5, 2.4, 20]
does not work: these numbers aren't compatible with Integer
. 但是对于单态签名, mult [1.5, 2.4, 20]
不起作用:这些数字与Integer
不兼容。 You don't want to restrict the function to integers, you just want it to work with any number type and always get a result of the same type as the elements. 您不希望将函数限制为整数,只是希望它可以使用任何数字类型,并始终获得与元素相同类型的结果。 Ie, you basically want the signature 即,你基本上想要签名
mult :: ∀ a . [a] -> a
...to be read "for all types a
, the function mult
takes a list whose elements have type a
, and gives a single a
-value as the result. The ∀
is implicit in Haskell when you have such type variables, ie you could as well make it ...要读取“对于所有类型a
,函数mult
采用其元素具有类型a
的列表,并给出单个a
值作为结果。当你有这样的类型变量时, ∀
隐含在Haskell中,即你也可以做到
mult :: [a] -> a
That doesn't work yet though, because the function must be able to multiply elements. 但这不起作用,因为该函数必须能够乘以元素。 But that is not possible for all types, only for number types . 但这对所有类型都不可能,仅适用于数字类型 。 Hence you add the constraint 因此,您添加约束
mult :: Num a => [a] -> a
For posList
it's much the same thing: the signature is essentially 对于posList
来说,它是完全相同的:签名本质上是
posList :: [a] -> [a]
but you also need to be able to compare ( Ord
) the elements with 0
( Num
). 但是你还需要能够将元素与0
( Num
)进行比较( Ord
)。 Thus the constraint 因此约束
posList :: (Num a, Ord a) => [a] -> [a]
In case of evenList
, the numerical operations are (+)
, (==)
and mod
. 在evenList
情况下,数值运算是(+)
, (==)
和mod
。 So in principle we need Num
, Eq
and Integral
, but Integral
has Num
and Eq
as superclasses anyway, so that alone is sufficient: 因此原则上我们需要Num
, Eq
和Integral
,但Integral
无论如何都有Num
和Eq
作为超类 ,所以仅此就足够了:
evenList :: Integral a => [a] -> Bool
...which is not the most general form yet, though. ......但是,这还不是最常见的形式。 You reduce that list with a fold, but lists aren't the only thing that can be folded, for instance you can also fold arrays, maps and Maybe
values. 您可以使用折叠来减少该列表,但列表不是唯一可以折叠的内容,例如您还可以折叠数组,贴图和Maybe
值。 The type class for all containers that can be folded is called, you won't guess it, Foldable
. 可以折叠的所有容器的类型类都被调用,你不会猜它, Foldable
。 So we end up with 所以我们最终得到了
evenList :: (Integral a, Foldable t) => t a -> Bool
You could apply the same generalisation to mult
and trueList
: 您可以对mult
和trueList
应用相同的泛化:
mult :: (Num a, Foldable t) => t a -> a
trueList :: Foldable t => t Bool -> Bool
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.