◄ WORLD V · SONNY 5DART 250 · a helldive at the net

THE TYPECLASS ad-hoc polymorphism made principled — carry the operations with the type

How do you write (==) for many types when each compares differently? A typeclass declares an interface (class Eq a where (==) : a → a → Bool); each type provides an instance; and the compiler, at each call, passes the right instance as a hidden dictionary of operations. This is Wadler & Blott's answer to Strachey's ad-hoc polymorphism — different behavior per type, but resolved by the type checker, not by runtime tags. Dictionary-passing is the whole trick: a typeclass constraint Eq a => compiles to an extra argument, the dictionary.

THE TECHNIQUE a constraint compiles to a hidden dictionary of operations

An Eq instance is a dictionary carrying (==). The demo dispatches through the dictionary on two inputs: live demo


HISTORY & CREDIT Wadler & Blott, 1989

“Overloading is a runtime lookup on the value's tag.” — a typeclass resolves the overload at compile time from the type, then passes the chosen operations along explicitly. No runtime tag, no guessing — the dictionary is decided before the program runs. cited

1989 · Philip Wadler & Stephen Blott — “How to make ad-hoc polymorphism less ad hoc” (POPL): typeclasses + dictionary-passing translation.
lineage · answers Strachey's ad-hoc / parametric split with a principled ad-hoc.
now · Haskell classes, Rust traits, Swift protocols, Scala given/using.

The constraint Eq a => is a function argument in disguise: the dictionary of operations for a. Overloading becomes ordinary passing — ad hoc made principled. Wadler-Blott 1989

RECOMMEND FOR I-13 dictionary dispatch of (==), computed

On the canonical compiler, dispatching (==) through the Eq dictionary gives 5==5 → 1 and 5==6 → 0:

$ i13 run t_typeclass.i13 # dispatch eq through the dictionary dict_eq_55 = 1 dict_eq_56 = 0 -- the Eq instance, passed explicitly
Recommend: i13 does the runtime half of this and skips the type half. You can pass a “dictionary” as an array of operation codes and dispatch on it by hand — i13 has functions and arrays — but there is no Eq a => constraint for the checker to infer and insert the dictionary for you. Ad-hoc polymorphism is available as a coding pattern, not a language feature; the compile-time resolution that makes typeclasses safe and invisible is exactly the types: NOT COVERED layer i13 declines.