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?
take sort
as an example. it's easy to write sort :: Ord a => [a] -> [a]
in terms of sortBy
:
sort :: Ord a => [a] -> [a]
sort = sortBy compare
but the other way around seems tricky, so far the best I can do is to go a bit "object-oriented":
import qualified Data.List as L
data OrdVal a = OV (a -> a -> 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 -> a -> Ordering) -> [a] -> [a]
sortBy cmp = map unOV . L.sort . map (OV cmp)
where
unOV (OV _ v) = v
But this sounds more like a hack than proper solution.
so I'd like to know:
- are there better ways for this specific example?
- what are the general techniques for converting between ad-hoc polymorphic functions and parametric ones?
Data.Set.insert
using a different ordering every time ... – Shawandacmp
functions inOrdVal a
values. If you do, then yourOrd
instance does not satisfy theOrd
laws. – Shawanda