  As originally proposed, type classes provide overloading and ad-hoc
definition, but can still be understood (and implemented) in terms of strictly
parametric calculi. This is not true of subsequent extensions of type classes.
Functional dependencies and equality constraints allow the satisfiability of
predicates to refine typing; this means that the interpretations of equivalent
qualified types may not be interconvertible. Overlapping instances and instance
chains allow predicates to be satisfied without determining the implementations
of their associated class methods, introducing truly non-parametric behavior.
We propose a new approach to the semantics of type classes, interpreting
polymorphic expressions by the behavior of each of their ground instances, but
without requiring that those behaviors be parametrically determined. We argue
that this approach both matches the intuitive meanings of qualified types and
accurately models the behavior of programs
