For someone new to Haskel but with some knowledge on OOP, e.g. Java, type classes (TC) could be one abstract concept, so interface in OOP is brought up as one example, for it’s a bit similar on many aspects. This post looks at what’s happening behind the scene, and it is almost one reprint of this talk from Simon at Oregon 13 summer school.
This is how Haskell looks like for TC:
class Num a (*) :: a -> a -> a instance Num int where (*) = square :: Num a => a -> a square x = x * x
After desugaring, the code becomes:
data Num a = MkNum (a->a->a) ... num :: Num Int num = MkNum <impl> .... square :: Num a -> a -> a square dictionary x = dictionary (*) x x
All the functions which work on TC end up with one extra argument, one dictionary namely. This dictionary contains the mapping from the operator name to operator definition.
The key difference, from my perspective, is that Num is not one type, even though it starts with capital letters, while interface, that starts with capital letters, could be used as one type.
The overhead is explained in this SO.