Typeclasses

TypeClasses, like Haskell’s Show, Eq and Ord assume that there is one cannonical implementation of a class for a given type. This assumption is not necessarily true: string order can be sorted short-lex, alphabetically, etc. String equivalence can be whitespace or case insensitive. All of these are meaningful in programs and the typeclass syntax does not allow easy disambiguation.

This arguments also holds for default implementations in the class. A typeclass (Eq a, Num a) => Mul a with a default implementation for mul like in the article picks a preferred implementation. It is reasonable that there may be different, incompatible but equally valid, implementations of mul that would also satisfy the Ring axioms.

Instead, what we want here is a Logical Signature. An opaque set of members equipped with a set of functions involving the members of varying aridity. For example,

signature Group a:
    zero: a
    member: a -> bool
    eq: a a -> bool
    add: a a -> a
    invert: a -> a
    
    member zero = true
    eq n n = true
    eq n m = eq m n
    eq n m /\ eq m k => eq n k
    add n (add m k) = add (n m) k
    ...

The combined functions and axioms form the signature. There can now be many different implementations, even over the same base type.

https://news.ycombinator.com/item?id=16948433

Kaes in his original paper partially solved this by giving typeclasses a local scope.