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?