title: Why typeclasses instead of just pattern matching?
body: <p>This is something of a philosophical question, but one I hope to have answered by official documentation or “word of god” (read: SPJ). Is there a specific reason that the Haskell committee chose to require explicit interfaces in the form of typeclasses rather than a more uniform solution based on pattern-matching?</p>
  
  <p>As an example, take <code>Eq</code>:</p>
  
  <pre><code>class Eq a where
      (==), (/=) :: a -&gt; a -&gt; Bool
      x == y = not $ x /= y
      x /= y = not $ x == y
  
  instance Eq Int where
      (==) = internalIntEq
  </code></pre>
  
  <p>Why could we not do something like this instead (bear with the pseudo-Haskell):</p>
  
  <pre><code>(==), (/=) :: a -&gt; a -&gt; Bool
  default x == y = not $ x /= y             -- 1
  default x /= y = not $ x == y
  
  (Int a) == (Int b) = a `internalIntEq` b  -- 2
  </code></pre>
  
  <p>That is, if Haskell were to allow pattern-matching of ordinary data types, then:</p>
  
  <ul>
  <li><p>Programmers could create ad-hoc classes, i.e., <code>instance</code> would be implicit (2)</p></li>
  <li><p>Types could still be inferred and matched statically (<code>SupportsEqualsEquals a =&gt; ...</code>)</p></li>
  <li><p>Default implementations would come “for free”</p></li>
  <li><p>Classes could readily be extended without breaking anything</p></li>
  </ul>
  
  <p>There would need to be a way to specify a default pattern (1) that, though declared before others, always matches last. Do any of these hypothetical features clash with something inherent in Haskell? Would it become difficult or impossible to correctly infer types? It seems like a powerful feature that’d gel very well with the rest of Haskell, so I figure there’s a good reason We Don’t Do It That Way™. Is this mechanism of ad-hoc polymorphism simply <em>too</em> ad-hoc?</p>