简体   繁体   English

Haskell类型签名

[英]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. 所以,我知道你可以用不同的方式更容易地完成这些功能,但我有使用更高阶函数mapfilterfoldr赋值,所以我必须这样做。 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? 无论如何,我理解这些功能是如何工作的,因为我是编写它们的人,我不理解的是那些术语IntegralFoldable ,它们是什么意思? 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 ). 但是你还需要能够将元素与0Num )进行比较( 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: 因此原则上我们需要NumEqIntegral ,但Integral无论如何都有NumEq作为超类 ,所以仅此就足够了:

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 : 您可以对multtrueList应用相同的泛化:

mult :: (Num a, Foldable t) => t a -> a
trueList :: Foldable t => t Bool -> Bool

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM