Introduction to Type Classes
Get introduced to the concept of type classes.
We'll cover the following
In the previous lesson, we defined our own data type for geometric shapes. In order to make them printable, we had to add deriving (Show)
to our type declaration.
Show
is an example of a Haskell type class. We also encountered the type class Eq
, already, in type annotations of polymorphic functions (e.g. elem
), where it acted as a constraint. In this lesson, we will learn in more detail what type classes are and how we can use them with our data types.
The Show
type class
A type class is a collection of types that share a common property. For example, the type class Show
is the class of all types that can be turned into a string using the show
function (note the difference in capitalization). Its definition is:
class Show a where
show :: a -> String
A type class declaration starts with the class
keyword. What follows is the name of the class (Show
) and a type variable a
. After the where
keyword, follow the operations that the members of the type class should support. This means that every type a
, which belongs to the Show
type class, must support the operation show
. This turns the value of type a
into a string. In that sense, type classes behave similarly to interfaces of object-oriented programming languages.
Most of Haskell’s predefined data types; such as numbers, characters, strings, tuples, and lists; are members of Show
. Notable exceptions are function types that cannot be turned into strings.
Prelude> show 5
"5"
Prelude> show ([1],'c')
"([1],'c')"
Prelude> show (\x -> x + 1)
<interactive>:27:1: error:
• No instance for (Show (Integer -> Integer))
arising from a use of ‘show’
(maybe you haven't applied a function to enough arguments?)
• In the expression: show (\ x -> x + 1)
In an equation for ‘it’: it = show (\ x -> x + 1)
Deriving type classes
As we saw in the previous lesson, type class instances can be automatically derived. All we need to do is add deriving (Show)
at the end of our data
declaration.
data Coordinates = Coordinates Double Double deriving (Show)
In that case, the compiler will automatically create a Show
instance for a type with an inferred show
implementation. Of course, this raises the question of what this implementation looks like.
In general, the derived show
implementation prints types the same way that they are constructed. When we construct a Coordinates
value like Coordinates 3.0 5.5
, this means that the derived show
implementation will print it as "Coordinates 3.0 5.5"
.
Implementing type classes
Sometimes, the default Show
instance derived by the compiler will not be to our liking. For example, we might want to print a coordinates pair Coordinates 3.0 5.5
as "(3.0, 5.5)"
. In that case, we must refrain from deriving the Show
instance and implement it ourselves. This can be done by using an instance
declaration.
Get hands-on with 1200+ tech skills courses.