title: good way to convert between ad-hoc polymorphic functions and parametric polymorphic ones
body: <p>I'm wondering if there are general ways to convert between ad-hoc polymorphic functions and parametric polymorphic ones. In other words, given an ad-hoc polymorphic function, how to implement its parametric counterpart? and what about the other way around?</p>
  
  <p>take <code>sort</code> as an example. it's easy to write <code>sort :: Ord a =&gt; [a] -&gt; [a]</code> in terms of <code>sortBy</code>:</p>
  
  <pre><code>sort :: Ord a =&gt; [a] -&gt; [a]
  sort = sortBy compare
  </code></pre>
  
  <p>but the other way around seems tricky, so far the best I can do is to go a bit "object-oriented":</p>
  
  <pre><code>import qualified Data.List as L
  
  data OrdVal a = OV (a -&gt; a -&gt; Ordering) a
  
  instance Eq (OrdVal a) where
      (OV cmp a) == (OV _ b) = a `cmp` b == EQ
  
  instance Ord (OrdVal a) where
      (OV cmp a) `compare` (OV _ b) = a `cmp` b
  
  sortBy :: (a -&gt; a -&gt; Ordering) -&gt; [a] -&gt; [a]
  sortBy cmp = map unOV . L.sort . map (OV cmp)
    where
      unOV (OV _ v) = v
  </code></pre>
  
  <p>But this sounds more like a hack than proper solution.</p>
  
  <p>so I'd like to know:</p>
  
  <ol>
  <li>are there better ways for this specific example?</li>
  <li>what are the general techniques for converting between ad-hoc polymorphic functions and parametric ones?</li>
  </ol>