Type signature types for lists, etc
How would you define the following type signatures in plain english:
Ord a => ...
Eq a => ...
Num a => ...
Could you describe the meaning of t开发者_Go百科hese and let me know what the differences are (in terms of how I would explain it to someone else)?
Thanks.
These are all examples of "class constraints": they constrain what types can be used in place of the type variable which follows them (a
in this case), requiring that it belong to a particular type class. Ord
, Eq
and Num
are examples of type classes.
Ord a => ...
meansa
is a type which has a natural notion of order associated with it. For example, integers can be naturally arranged from smaller to larger. In mathematical terms, there exists a total order ona
. An obvious example a function which requires this constraint issort :: Ord a => [a] -> [a]
; read this signature as saying thatsort
only works on lists of things which can be put in order relative to one another.Eq a => ...
meansa
is a type whose members can be compared to each other for some notion of equality. In mathematical terms, there exists an equivalence relation ona
. Note that this is a superclass ofOrd
, meaning anything that has a notion of ordering must also have a notion of equivalence. An example of a function which requires this constraint iselem :: Eq a => a -> [a] -> Bool
(which determines if a list contains a given element); read this signature as saying thatelem
only works on lists of things which can be compared to one another for equality. If you think about how you would writeelem
yourself, that should make sense.Num a => ...
meansa
is a numeric type, meaning it supports some basic arithmetical operations:+
,*
,-
,abs
. I believe this is roughly similar to the mathematical notion of a ring. Basically all the types you think of as "number types" belong to this class:Int
,Double
, etc. You would see theNum a =>
constraint in front of a signature if the function was written to work generically with any kind of number. For example,sum :: Num a => [a] -> a
, which sums all the elements of a list of numbers, can work equally well on[Int]
,[Double]
,[Rational]
, etc... all it has to do is add up its contents, no matter what kind of numbers they are. But numbers they must be!
Basically, these type classes/constraints are an approach to "principled overloading" of functions. We can use (==) :: Eq a => a -> a -> Bool
on various types, but not just any types. Some things, for example functions, don't make sense to compare for equality (perhaps because equality isn't decidable for that type), and it never makes sense to compare two things of different types for equality (contrast this with Java, where you can compare any two objects of possibly different types for equality).
For further (very accessible) reading on type classes and constraints, I highly recommend Learn You a Haskell.
精彩评论