Haskell type classes are great for most situations, except when they fail it can be quite spectacular. I think the "magic" of type classes comes from two things:
- All instances are thrown into one global namespace, so we don't need to worry about where to find the right one.
- There can be at most one instance per type. Hence there's no ambiguity about which one to pick.
These make it easy for the machine to pick the correct instance automatically. Unfortunately, it also means that every time we import or upgrade a library, there's the chance that it will break things by exposing an instance that clashes with what we have.
The "backpack" stuff looks interesting in this regard, although it seems very over-engineered (mostly due to legacy concerns).