Skip main navigation
We use cookies to give you a better experience, if that’s ok you can close this message and carry on browsing. For more info read our cookies policy.
We use cookies to give you a better experience. Carry on browsing if you're happy with this, or read our cookies policy for more information.
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
    *Main> 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]
    *Main> ['a'..'z']

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:

Contact FutureLearn for Support