## Want to keep learning?

This content is taken from the The University of Glasgow's online course, Functional Programming in Haskell: Supercharge Your Coding. Join the course to learn more.
6.3

## The University of Glasgow # Type Classes in more Detail

## Type class and instance declarations

### Defining type classes

• A type class is a set of types for which some operations are defined.

• Haskell has some standard type classes that are defined in the Standard Prelude.

• You can also define your own.

### A type for bright colors

Suppose we’re computing with colors. Here’s a type, and a couple of functions.

    data Bright
= Blue
| Red

darkBright :: Bright -> Bool
darkBright Blue = True
darkBright Red  = False

lightenBright :: Bright -> Bright
lightenBright Blue = Red
lightenBright Red = Red


### A type for milder colors

Now, suppose we have a different type that needs similar functions.


data Pastel
= Turquoise
| Tan

darkPastel :: Pastel -> Bool
darkPastel Turquoise = True
darkPastel Tan       = False

lightenPastel :: Pastel -> Pastel
lightenPastel Turquoise = Tan
lightenPastel Tan       = Tan


### Defining a type class

• Both of our color types have functions to decide whether it’s dark, or to lighten it.

• We can define a class $$Color$$ and its corresponding functions.


class Color a where
dark :: a -> Bool
lighten :: a -> a


This says

• $$Color$$ is a type class

• The type variable $$a$$ stands for a particular type that is in the class $$Color$$

• For any type $$a$$ in $$Color$$, there are two functions you can use: $$dark$$ and $$lighten$$, with the specified types.

### Defining instances for the type class

• An $$instance$$ declaration says that a type is a member of a type class.

• When you declare an instance, you need to define the class functions.

• The following says that the type $$Bright$$ is in the class $$Color$$, and for that instance, the $$dark$$ function is actually $$darkBright$$.


instance Color Bright where
dark = darkBright
lighten = lightenBright

• Similarly, we can declare that $$Pastel$$ is in $$Color$$, but it has different functions to implement the class operations.

instance Color Pastel where
dark = darkPastel
lighten = lightenPastel


## Predefined type classes

Haskell provides several standard type classes. We have a look at two of them: $$Num$$ and $$Show$$.

### The Num class

• $$Num$$ is the class of numeric types.
• Here is (part of) its class declaration:
    class Num a where
(+), (-), (*) :: a -> a -> a


#### Num instances

• There are many numeric types; two of them are $$Int$$ and $$Double$$.

• There are primitive monomorphic functions that perform arithmetic on these types (these aren’t the real names):

addInt, subInt, mulInt :: Int -> Int -> Int
addDbl, subDbl, mulDbl :: Double -> Double -> Double

instance Num Int where
(-) = subInt
(*) = mulInt

instance Num Double where
(-) = subDbl
(*) = mulDbl


#### Hierarchy of numeric classes

• There are some operations (addition) that are valid for all numeric types.

• There are some others (e.g. trigonometric functions) that are valid only for some numeric types.

• Therefore there is a rich hierarchy of subclasses, including

• $$Integral$$ — class of numeric types that represent integer values, including $$Int$$, $$Integer$$, and more.

• $$Fractional$$ — class of types that can represent fractions.

• $$Floating$$ — class containing $$Float$$, $$Double$$, etc.

• $$Bounded$$ — class of numeric types that have a minimal and maximal element.

• $$Bits$$ — class of types where you can access the representation as a sequence of bits, useful for systems programming and digital circuit design.

• If you want to get deeply into numeric classes and types, refer to the Haskell documentation.

### The Show class

• We have been using $$show$$ to convert a data value to a string, which can then be written to output.

• Some values can be “shown”, but not all.

• For example, it is impossible in general to show a function.

• Therefore $$show$$ needs a type class!

• $show :: Show\, a \Rightarrow a \rightarrow \,String$

#### Defining your own Show instance


data Foo = Bar | Baz


We might want our own peculiar string representation:


instance Show Foo where
show Bar = "it is a bar"
show Baz = "this is a baz"


Recall that when you enter an expression $$exp$$ into ghci, it prints $$show exp$$. So we can try out our strange instance declaration:


*Main> Bar
it is a bar
*Main> Baz
this is a baz


#### Deriving Show

This is a similar type, but it has a $$deriving$$ clause.


data Foo2 = Bar2 | Baz2


Haskell will automatically define an instance of $$show$$ for $$Foo2$$, using the obvious definition:


*Main> Bar2
Bar2
*Main> Baz2
Baz2


### More standard typeclasses

Here is a summary of some of the type classes defined in the standard libraries.

• $$Num$$ — numbers, with many subclasses for specific kinds of number.

• $$Read$$ — types that can be “read in from” a string.

• $$Show$$ — types that can be “shown to” a string.

• $$Eq$$ — types for which the equality operator $$==$$ is defined.

• $$Ord$$ — types for which you can do comparisons like $$<$$, $$>$$, etc.

• $$Enum$$ — types where the values can be enumerated in sequence; this is used for example in the notation $$[1..n]$$ and $$'a'..'z'$$.


*Main> [1..10]
[1,2,3,4,5,6,7,8,9,10]
*Main> ['a'..'z']
"abcdefghijklmnopqrstuvwxyz"