Рассмотрим следующую ситуацию:
slow_func :: Eq a => [a] -> [a]
fast_func :: Ord a => [a] -> [a]
У меня есть две функции, slow_func
и fast_func
. Эти функции являются различными реализациями одной и той же абстрактной функции (они выполняют одно и то же), но одна работает быстрее другой. Более быстрая реализация доступна только в том случае, если можно заказать тип a
. Есть ли способ построить функцию, которая действует как fast_func
когда это возможно, и в slow_func
случае возвращается к slow_func
?
as_fast_as_possible_func :: Eq a => [a] -> [a]
Я уже пробовал следующее:
{-# LANGUAGE OverlappingInstances #-}
class Func a where
as_fast_as_possible_func :: [a] -> [a]
instance Ord a => Func a where
as_fast_as_possible_func = fast_func
instance Eq a => Func a where
as_fast_as_possible_func = slow_func
К сожалению, это не компилируется, генерируя следующую ошибку:
Duplicate instance declarations:
instance Ord a => Func a
-- Defined at [...]
instance Eq a => Func a
-- Defined at [...]
Причина в том, что OverlappingInstances
хочет, чтобы один из экземпляров был наиболее специализированным в отношении спецификации экземпляра, игнорируя его контекст (вместо того, чтобы использовать наиболее ограничивающий контекст, который нам здесь нужен).
Есть ли способ сделать это?