Haskell/Classes and types
From Wikibooks, the open-content textbooks collection
[edit] Classes and Types
[edit] Simple Type Constraints
So far we have seen how to declare classes, how to declare types, and how to declare that types are instances of classes. But there is something missing. How do we declare the type of a simple arithmetic function?
plus x y = x + y
Obviously x and y must be of the same type because you can't add different types of numbers together. So how about:
plus :: a -> a -> a
which says that plus takes two values and returns a new value, and all three values are of the same type. But there is a problem: the arguments to plus need to be of a type that supports addition. Instances of the class Num support addition, so we need to limit the type signature to just that class. The syntax for this is:
plus :: Num a => a -> a -> a
This says that the type of the arguments to plus must be an instance of Num, which is what we want.
You can put several limits into a type signature like this:
foo :: (Num a, Show a, Show b) => a -> a -> b -> String foo x y t = show x ++ " plus " ++ show y ++ " is " ++ show (x+y) ++ ". " ++ show t
This says that the arguments x and y must be of the same type, and that type must be an instance of both Num and Show. Furthermore the final argument t must be of some (possibly different) type that is also an instance of Show.
You can omit the parentheses for a single constraint, but they are required for multiple constraints. Actually it is common practice to put even single constraints in parentheses because it makes things easier to read.
[edit] More Type Constraints
You can put a type constraint in almost any type declaration. The only exception is a type synonym declaration. The following is not legal:
type (Num a) => Foo a = a -> a -> a
But you can say:
data (Num a) => Foo a = F1 a | F2 Integer
This declares a type Foo with two constructors. F1 takes any numeric type, while F2 takes an integer.
You can also use type parameters in newtype and instance declarations. Class inheritance (see the previous section) also uses the same syntax.