Skip main navigation

Type Classes in more Detail

In this article we take a closer look at type classes
Temple silhouet against sunset sky
© University of Glasgow

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
deriving (Read, Show)

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
deriving (Read, Show)

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
(+) = addInt
(-) = subInt
(*) = mulInt

instance Num Double where
(+) = addDbl
(-) = 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
deriving (Read, Show)
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"
© University of Glasgow
This article is from the free online

Functional Programming in Haskell: Supercharge Your Coding

Created by
FutureLearn - Learning For Life

Our purpose is to transform access to education.

We offer a diverse selection of courses from leading universities and cultural institutions from around the world. These are delivered one step at a time, and are accessible on mobile, tablet and desktop, so you can fit learning around your life.

We believe learning should be an enjoyable, social experience, so our courses offer the opportunity to discuss what you’re learning with others as you go, helping you make fresh discoveries and form new ideas.
You can unlock new opportunities with unlimited access to hundreds of online short courses for a year by subscribing to our Unlimited package. Build your knowledge with top universities and organisations.

Learn more about how FutureLearn is transforming access to education