Temple silhouet against sunset sky

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
      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 and its corresponding functions.


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

This says

  • is a type class

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

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

Defining instances for the type class

  • An 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 is in the class , and for that instance, the function is actually .


    instance Color Bright where
      dark = darkBright
      lighten = lightenBright
  • Similarly, we can declare that is in , 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: and .

The Num class

  • 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 and .

  • 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

    • — class of numeric types that represent integer values, including , , and more.

    • — class of types that can represent fractions.

    • — class containing , , etc.

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

    • — 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 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 needs a type class!

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 into ghci, it prints . 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 clause.


    data Foo2 = Bar2 | Baz2
      deriving (Read, Show)

Haskell will automatically define an instance of for , 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.

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

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

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

  • — types for which the equality operator is defined.

  • — types for which you can do comparisons like , , etc.

  • — types where the values can be enumerated in sequence; this is used for example in the notation and .


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

Share this article:

This article is from the free online course:

Functional Programming in Haskell: Supercharge Your Coding

University of Glasgow

Get a taste of this course

Find out what this course is like by previewing some of the course steps before you join: