Classes and types

## Contents

Back in Type basics II we had a brief encounter with type classes as the mechanism used with number types. As we hinted back then, however, classes have many other uses.

Broadly speaking, the point of type classes is to ensure that certain operations will be available for values of chosen types. For example, if we know a type belongs to (or, to use the jargon, instantiates) the class `Fractional`, then we are guaranteed to, among other things, be able to perform real division with its values.[1]

## Classes and instances

Up to now we have seen how existing type classes appear in signatures such as:

```(==) :: (Eq a) => a -> a -> Bool
```

Now it is time to switch perspectives. First, we quote the definition of the `Eq` class from Prelude:

```class  Eq a  where
(==), (/=) :: a -> a -> Bool

-- Minimal complete definition:
--      (==) or (/=)
x /= y     =  not (x == y)
x == y     =  not (x /= y)
```

The definition states that if a type `a` is to be made an instance of the class `Eq` it must support the functions `(==)` and `(/=)` - the class methods - both of them having type `a -> a -> Bool`. Additionally, the class provides default definitions for `(==)` and `(/=)` in terms of each other. As a consequence, there is no need for a type in `Eq` to provide both definitions - given one of them, the other will be generated automatically.

With a class defined, we proceed to make existing types instances of it. Here is an arbitrary example of an algebraic data type made into an instance of `Eq` by an instance declaration:

```data Foo = Foo {x :: Integer, str :: String}

instance Eq Foo where
(Foo x1 str1) == (Foo x2 str2) = (x1 == x2) && (str1 == str2)
```

And now we can apply `(==)` and `(/=)` to `Foo` values in the usual way:

```*Main> Foo 3 "orange" == Foo 6 "apple"
False
*Main> Foo 3 "orange" /= Foo 6 "apple"
True
```

A few important remarks:

• The class `Eq` is defined in the Standard Prelude. This code sample defines the type `Foo` and then declares it to be an instance of `Eq`. The three definitions (class, data type, and instance) are completely separate and there is no rule about how they are grouped. This works both ways: you could just as easily create a new class `Bar` and then declare the type Integer to be an instance of it.
• Classes are not types, but categories of types; and so the instances of a class are types instead of values.[2]
• The definition of `(==)` for `Foo` relies on the fact that the values of its fields (namely `Integer` and `String`) are also members of `Eq`. In fact, almost all types in Haskell are members of Eq (the most notable exception being functions).
• Type synonyms defined with type keyword cannot be made instances of a class.

## Deriving

Since equality tests between values are commonplace, in all likelihood most of the data types you create in any real program should be members of Eq. A lot of them will also be members of other Prelude classes such as Ord and Show. To avoid large amounts of boilerplate for every new type, Haskell has a convenient way to declare the "obvious" instance definitions using the keyword deriving. So, Foo would be written as:

```data Foo = Foo {x :: Integer, str :: String}
deriving (Eq, Ord, Show)
```

This makes Foo an instance of Eq with an automatically generated definition of == exactly equivalent to the one we just wrote, and also makes it an instance of Ord and Show for good measure.

You can only use deriving with a limited set of built-in classes, which are described very briefly below:

Eq
Equality operators == and /=
Ord
Comparison operators < <= > >=; min, max, and compare.
Enum
For enumerations only. Allows the use of list syntax such as [Blue .. Green].
Bounded
Also for enumerations, but can also be used on types that have only one constructor. Provides minBound and maxBound as the lowest and highest values that the type can take.
Show
Defines the function show, which converts a value into a string, and other related functions.
Defines the function read, which parses a string into a value of the type, and other related functions.

The precise rules for deriving the relevant functions are given in the language report. However, they can generally be relied upon to be the "right thing" for most cases. The types of elements inside the data type must also be instances of the class you are deriving.

This provision of special "magic" function synthesis for a limited set of predefined classes goes against the general Haskell philosophy that "built in things are not special", but it does save a lot of typing. Besides that, deriving instances stops us from writing them in the wrong way (an example: an instance of `Eq` such that `x == y` would not be equal to `y == x` would be flat out wrong). [3]

## Class inheritance

Classes can inherit from other classes. For example, here is the main part of the definition of Ord in Prelude:

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

The actual definition is rather longer and includes default implementations for most of the functions. The point here is that Ord inherits from Eq. This is indicated by the => notation in the first line, which mirrors the way classes appear in type signatures. Here, it means that for a type to be an instance of Ord it must also be an instance of Eq, and hence needs to implement the == and /= operations.[4]

A class can inherit from several other classes: just put all the ancestor classes in the parentheses before the =>. Let us illustrate that with yet another Prelude quote:

```class  (Num a, Ord a) => Real a  where
-- | the rational equivalent of its real argument with full precision
toRational          ::  a -> Rational
```

## Standard classes

This diagram, copied from the Haskell Report, shows the relationships between the classes and types in the Standard Prelude. The names in bold are the classes, while the non-bold text stands for the types that are instances of each class ((->) refers to functions and [], to lists). The arrows linking classes indicate the inheritance relationships, pointing to the inheriting class.

## Type constraints

With all pieces in place, we can go full circle by returning to the very first example involving classes in this book:

```(+) :: (Num a) => a -> a -> a
```

`(Num a) =>` is a type constraint, which restricts the type `a` to instances of the class `Num`. In fact, `(+)` is a method of `Num`, along with quite a few other functions (notably, `(*)` and `(-)`; but not `(/)`).

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
```

Here, 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. This example also displays clearly how constraints propagate from the functions used in a definition (in this case, `(+)` and `show`) to the function being defined.

### Other uses

Beyond simple type signatures, type constraints can be introduced in a number of other places:

• `instance` declarations (typical with parametrized types);
• `class` declarations (constraints can be introduced in the method signatures in the usual way for any type variable other than the one defining the class[5]);
• `data` declarations,[6] where they act as constraints for the constructor signatures.

Note

Type constraints in `data` declarations are less useful than it might seem at first. Consider:

```data (Num a) => Foo a = F1 a | F2 a String
```

Here, Foo is a type with two constructors, both taking an argument of a type `a` which must be in `Num`. However, the `(Num a) =>` constraint is only effective for the F1 and F2 constructors, and not for other functions involving `Foo`. Therefore, in the following example...

```fooSquared :: (Num a) => Foo a -> Foo a
fooSquared (F1 x)   = F1 (x * x)
fooSquared (F2 x s) = F2 (x * x) s
```

... even though the constructors ensure `a` will be some type in `Num` we can't avoid duplicating the constraint in the signature of `fooSquared`.[7]

## A concerted example

To provide a better view of the interplay between types, classes, and constraints, we will present a very simple and somewhat contrived example. We will define a `Located` class, a `Movable` class which inherits from it, and a function with a `Movable` constraint implemented using the methods of the parent class, i.e. `Located`.

```-- Location, in two dimensions.
class Located a where
getLocation :: a -> (Int, Int)

class (Located a) => Movable a where
setLocation :: (Int, Int) -> a -> a

-- An example type, with accompanying instances.
data NamedPoint = NamedPoint
{ pointName :: String
, pointX    :: Int
, pointY    :: Int
} deriving (Show)

instance Located NamedPoint where
getLocation p = (pointX p, pointY p)

instance Movable NamedPoint where
setLocation (x, y) p = p { pointX = x, pointY = y }

-- Moves a value of a Movable type by the specified displacement.
-- This works for any movable, including NamedPoint.
move :: (Movable a) => (Int, Int) -> a -> a
move (dx, dy) p = setLocation (x + dx, y + dy) p
where
(x, y) = getLocation p
```

Do not read too much into the `Movable` example just above; it is merely a demonstration of class-related language features. It would be a mistake to think that every single functionality which might be conceivably generalized, such as `setLocation`, needs a type class of its own. In particular, if all your `Located` instances should be able to be moved as well then `Movable` is unnecessary - and if there is just one instance there is no need for type classes at all! Classes are best used when there are several types instantiating it (or if you expect others to write additional instances) and you do not want users to know or care about the differences between the types. An extreme example would be `Show`: general-purpose functionality implemented by an immense number of types, about which you do not need to know a thing about before calling `show`. In the following chapters, we will explore a number of important type classes in the libraries; they provide good examples of the sort of functionality which fits comfortably into a class.
3. There are ways to make the magic apply to other classes. GHC extensions allow `deriving` for a few other common classes for which there is only one correct way of writing the instances, and the GHC generics machinery make it possible to generate instances automatically for custom classes.
4. If you check the full definition in the Prelude specification, the reason for that becomes clear: the default implementations involve applying `(==)` to the values being compared.
6. And `newtype` declarations as well, but not `type`.