What are type classes? A definition of a type class is a function that takes some type variables of a type and returns a new type that depends on thoose type variables. So it is like a function that operates on types.
This means that you have a free type variable that you can define some type constraint on a “class” of functions. This free type variable is called parametrically polymorphism. If this sound familiar to some Java and C# developers, this is also called generics.
In C# code:
In javscript code:
So why do you want this? When we can write this for every class that we needs a an equals method. What does this buy us? It seems like a zero sum game.
The win is expressiveness with type safty. You can write a definition once and use that definition for every class that needs to implement it.
Duck typeing is not safe!
A common usecase for type is collections where the type of the collection varries. But do you want to write a implementation for every type that you put in your colletion? Probably not…
You want some generic data strcture that operates on the elements for some type. And these elemets in our is like a wrapper around the real type. This is the reason that we don’t need to care about the real type.
In .NET and C# type classes are realy common. Like
List<T>. The library to process collection is LINQ that have a generic functions that don’t care what is in the collections or how the collection works.
In a language that has a propper type system (Damas-Hindley-Milner type system, DHM for short) like in Haskell. Such type system automaticaly supports generics, it is a requirement of such a system. If the type system encounters a functions that has a free type variable that is not type dependant then the function is automatically a generic function.
The type system knows that I don’t do any type dependant function calls or operators on the value. So the type system keeps the type for this function free.
But if you add a type dependant function call to it then the function is no longer generic.
Then the types becomes:
So the type system automatically checks so the function that you are using only take argument that it can handle. So no unexpected behaviour happens.
If you would have a DHM type system in your language. You would not have to write a single type in your code (There are some exeptions). And it is smarter then you! How many times have your provided the wrong type to the compiler when you write your signature? I do it alot when I write C# code.
This is C style nomenclature typeing:
This is DHM typeing:
Types are collection of things that belong to that set. Functions are mappnings from one type set to another.
A type definition of this function would look like:
A function can be viewed a set of rules to follow to get a value. But it can also be viewed as large lookup table that contains all the possible values. We looked at this in part 1 when we discussed function memoization.
Function composition in a type category
So when two functions are composed you can view this as two lookups. Or combine these two lookups into a single lookup table from
A javscript version of this could look like this:
A monoid is a type class and a set of rules (methods on the monoid). And those rules obey associativity and identity (let call them metar ules). The most common example is clock arithmetic.
Let our type class be
var numbers = _.range(0,11); and the rule be
var rule = x => x % 12.
Is associativity met for
I won’t prove that modulo addition is associative but here is a proof for you sceptics.
Is identity met for
So we have shown that the meta rules are uphold for the add method inside our type
numbers and our
rule. So we have prooved that
rule form a monoid.
So why complicate it? Because math, thats why!
If you have a monoid it is garantied with mathematical surety that you can’t fall outside the monoid by mistake.
It is like a guardrail for functions applied to types. You are garantied that the value is allways well defined within the specified type of the monoid.
The checking of associativity and identity should be implemented in the typechecker or compiler. And give the error before runtime to the programmer.
The monoid is a special case of a monad. Or rather a monad is a generalization of a monoid.
The next part in the series will be about functors and the ever so elusive monad.