Using the GHC RULES pragma, it is possible to specialise a polymorphic function for specific types. Example from the Haskell report:
genericLookup :: Ord a => Table a b -> a -> b
intLookup :: Table Int b -> Int -> b
{-# RULES "genericLookup/Int" genericLookup = intLookup #-}
This would make GHC use intLookup on an integer-indexed table and the generic version otherwise, where intLookup would probably be more efficient.
I would like to accomplish something similar, using functions like the following (slightly simplified) ones:
lookup :: Eq a => [(a, b)] -> a -> b
lookupOrd :: Ord a => [(a, b)] -> a -> b
where lookupOrd creates a Map from the input list and then uses Map.lookup, which requires that a be a member of Ord.
Now I would like to tell GHC that lookupOrd should be used instead of lookup whenever a is indeed a member of the Ord type class. The following rule, however, does not typecheck:
{-# RULES "lookup/Ord" lookup = lookupOrd #-}
GHC (rightfully) complains that it cannot deduce (Ord a) from the context (Eq a). Is there a rewrite rule that would allow me to perform this sort of type class-based specialisation?