kuniga.me > NP-Incompleteness > Haskell – Typeclasses

04 Dec 2011

In this post I will comment the typeclass structure in Haskell. My main reference is chapter 6 of Real World Haskell [1].

## Typeclasses

Since Haskell supports parameterized types, we may want to define functions that accept parameters of such types. However, the function implementation will likely be different for each specific type “instance”.

Typeclass is a framework to provide this functionality. The basic syntax is as follows:

Despite the class keyword, a typeclass is quite different of a class that we are used to in object-oriented languages.

One case where typeclass is useful is in implementing the equality operator. Suppose we have two types Boolean and RGBColor:

We can define a typeclass containing an equality function, which receives two parameters of the same type parameterized a, and returns True if they are equal or False otherwise.

Then we can define an implementation for any type we’re interested in, using the instance construct. The syntax is similar to a typeclass, but we replace the parameterized type by the actual type and define the function implementation. For the case of Boolean and RGBColor, we have:

We can also provide default implementations for a typeclass by defining the implementation in the class structure. During runtime, the implementation used is always the most specific one.

For example, in the typeclass Compare, we can define the function different and define default implementations for it and also for the function equals:

## Deriving

In defining Boolean and RGBColor, we added deriving(Show). Essentially Show is a typeclass from the standard library. The function show in this typeclass transforms a generic type into a String.

Doing some tests in the terminal (ghci):

Note that the command :type uses a different syntax to say that the function show belongs to the typeclass Show.

We can write our own implementation for RGBColor instead of using the default. To do this, we remove the deriving(Show) statement and add:

According to [2], the derive functionality can only be used with a specific set of built-in typeclasses.

## Typeclass with list of parametric types

Imagine that we want to implement the equals() function for a list of Booleans. The first attempt would be:

In the above code, undefined is a wildcard type that does not cause compilation errors due to type mismatch, but does cause a runtime error. This technique of using undefined’s is interesting for compiling intermediate versions of your code even without implementing all the functions.

Anyway, we will see that such a code snippet leads to the following compilation error:

There are several ways to get around this error. One is to define a unique function for lists, which in the case of the function equals() can be called equalList():

The advantage in this case is that the default implementation should work for most cases, since in general the test for equality between two lists consists of checking if all elements in both are equal.

In case you want to define the implementation only for a list of a particular type (eg [Boolean]), you can encapsulate that list in a structure called newtype.

The newtype is similar to an algebraic data type (keyword data), with some differences such as the newtype requiring exactly one data constructor and the type of a newtype is resolved at compile time (unlike data) and therefore its use does not cause overhead in program execution [1]. So we could do:

Now we can implement the function, with the inconvenience of wrapping the data of the new type with Wrapper:

A good reference for these and other alternatives is the haskell wiki [3].

## Conclusion

I found this subject very complicated! To make matters worse, it seems that the book Real World Haskell I’m basing on, wrote chapters 5 and 6 very badly, giving very complex examples (maybe it’s the “real world” vision, but this is definitely not didactic), confusing and boring. There are several reviews that share this opinion.

Despite everything, I will continue my studies with this book, even if I only use the topics to guide me and look for explanations in references like [2] and [3].

## References

• [1] Real World Haskell - Chapter 6, by Bryan O’Sullivan, Don Stewart, and John Goerzen.
• [2] Wikibooks - Haskell/Classes and types
• [3] Haskell Wiki - List instance