Используя GHC RULES
прагма, можно специализировать полиморфную функцию для определенных типов. Пример из отчета Haskell:
genericLookup :: Ord a => Table a b -> a -> b
intLookup :: Table Int b -> Int -> b
{-# RULES "genericLookup/Int" genericLookup = intLookup #-}
Это приведет к тому, что GHC будет использовать intLookup
в таблице с индексом целых чисел и в общей версии, где intLookup
, вероятно, будет более эффективным.
Я хотел бы выполнить нечто подобное, используя следующие функции (несколько упрощенные):
lookup :: Eq a => [(a, b)] -> a -> b
lookupOrd :: Ord a => [(a, b)] -> a -> b
где lookupOrd
создает Map
из списка ввода, а затем использует Map.lookup
, для чего a
является членом Ord
.
Теперь я хотел бы сказать GHC, что lookupOrd
следует использовать вместо lookup
, когда a
действительно является членом класса типа Ord
. Однако следующее правило не проверяет тип:
{-# RULES "lookup/Ord" lookup = lookupOrd #-}
GHC (по праву) жалуется, что он не может вывести (Ord a)
из контекста (Eq a)
. Есть ли правило перезаписи, которое позволило бы мне выполнить такую специализацию на основе класса?