Creating Polymorphic Types

Get introduced to the creation of polymorphic types using examples from the Prelude.

So far, all the types that we created have been concrete types. But just like polymorphic functions, we can also create polymorphic types. We will study them in the context of types for better error handling.

The Maybe type

A polymorphic type is a type which contains one or more type variables. It can be seen as a recipe to create types by substituting the type variable with a concrete type.

As a first example, let’s look at the Maybe type from the Haskell Prelude that represents optional values. Its definition is

data Maybe a = Nothing | Just a

On the left side of the equation, there is the type variable a which can stand in for any type and can be used on the right hand side in the constructors. The Maybe type has two constructors:

  • Nothing, representing no value
  • Just, representing a present value of type a

If we replace a by Double, for example, we obtain the type Maybe Double. It contains Nothing as well as values like Just 3.5. Similarly, Just "Hello" would be a value of type Maybe String.

Using Maybe for error handling

The Maybe type is commonly used to represent computations that can fail. So far, we have worked with functions that lead to a runtime error in these cases. But, if we can recover from the failure, it would be better to return an optional value using Maybe and handle the error instead of crashing the program.

For example, when studying lists, we made use of the head function which returns the first element of a list. But, when called on an empty list, a runtime error occurs. Using Maybe we can write a polymorphic, safe version of head:

safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x

Any code that uses safeHead can then handle the error case by pattern matching on the returned Maybe value.

Get hands-on with 1400+ tech skills courses.