Могу ли я предоставить уточненную реализацию (также называемую переопределением в ООП) метода в экземпляре класса, когда тип также находится в другом классе?Или, по крайней мере, если этот другой класс является подклассом.
У меня есть класс C
с методом m
, подкласс S
из C
с методом s
и типом T a
так что есть экземпляры
class C a where m :: [a] -> Bool
class C a => S a where s :: a -> a -> Bool
instance C a => C (T a) where m = ...
instance S a => S (T a) where s = ...
как обычно.Теперь случается так, что когда T a
находится в подклассе (который я не могу знать, поскольку он зависит от a
), метод m
может быть реализован гораздо более эффективно (квадратичное и экспоненциальное время) с использованием s
.
Я попытался переопределить m
в реализации
instance S a => S (T a) where
s = ...
m = (all . uncurry) (=^=) . pairs -- override C.m
, но компилятор в основном ошибался, потому что m
не является публичным методом S
.Ну, это не так, но он унаследован в ОО-смысле.
Для конкретной цели специализированная версия m
может использоваться для всех случаев;это не значение по умолчанию для переопределения где-либо.
Редактировать: Поскольку запрос, конкретный код с небольшим количеством объяснения.
У меня есть класс Model
который имеет (среди прочего) метод con
, который проверяет список на согласованность.
class Model a where
con :: [a] -> Bool
Две модели могут образовывать модель стрелок.
data Arrow a b = [a] :->: b
lhs w = [ a | (u :->: _) <- w, a <- u ]
rhs w = [ b | (_ :->: b) <- w ]
Для конкретного экземпляра Model (Arrow a b)
, общая реализация con
очень дорога (обратите внимание powerset
в определении).
instance (Model a, Model b) => Model (Arrow a b) where
con w = all (\w' -> con (lhs w') `implies` con (rhs w')) (powerset w)
Существует подкласс CoherentModel
из Model
, который имеет метод (=^=)
, которыйпроверяет согласованность для двух объектов.Условием для согласованных моделей является согласованность списка, если все пары.
class Model a => CoherentModel a where
(=^=) :: a -> a -> Bool
a =^= b = con [a, b]
Класс CoherentModel
является на данный момент большим количеством документации, чем функция.
Итак, учитывая, чтомодель согласована, согласованность гораздо эффективнее проверять.
instance (Model a, CoherentModel b) => CoherentModel (Arrow a b) where
(u :->: a) =^= (v :->: b) = con (u ++ v) `implies` a =^= b
И в этом случае con
может быть реализовано с использованием
con = (all . uncurry) (=^=) . pairs
where
pairs :: [a] -> [(a,a)]
pairs [] = []
pairs [_] = []
pairs [x,y] = [(x,y)]
pairs (x:xs) = map ((,) x) xs ++ pairs xs
, но я не могу указатьэтот.Это не только для Arrow
, оно актуально для всех моделей с параметром.Я выбрал Arrow
, потому что улучшение значительно.