Chris James - Software developer and other things

What is a typeclass and why should you care

01 April 2014

Type systems are great because they protect you from lots of errors at compile time. However, sometimes it feels like it gets in your way and can make your code feel less flexible when you are trying to extend certain types that you may or may not have defined.

In dynamically typed languages this is less of a problem because of duck-typing. However, you get no safety here; if you pass in something that doesn’t quack you will get a runtime error.

Duck typing doesn't fix everything though. A human class might be able to quack with a "say" function; you would need to give your program some help in these instances

If you wish to write a generic function that operates on a variety of types, you may be tempted into writing an interface and ensuring all the types you care about implement them.

But this requires changing potentially lots of code and adding in a commonality that only you care about to solve a particular problem. Ask yourself, is this polymorphism truly useful for other people? Or are you polluting the namespace for your convenience (hint: the latter).

The GoF have a solution to this too, the adapter pattern. But every time someone wants to use your library they will have to take their type and wrap them up in an adapter. This feels clunky to me; and of course there is a better way.

Type classes to the rescue!

A type class T is an interface that defines a set of behaviours that a type Foo must implement in order to be of type T. Great, so what?

If you wish to have a polymorphic function, you can require evidence of a type class for the type which is being passed in. This can be any type because a developer can provide this evidence wherever they like; i.e not within the type itself.

This is a great strength of type classes because it addresses the flaws of the other approaches:


Scala provides sugar to make it so your function's type can reflect it's needs, rather than having it as a parameter. You can replace the function from above with the code below and it will continue to work.

This syntax can provide more flexibility in terms of not having to pass implicit parameters to other sub-functions; your function just requires "evidence" of a type-class.

However, people in your team may be more familiar with an implicit parameter so be sure to explain things whenever you introduce exotic symbols into your code-base.


Other links

I originally posted this at spiking the solution