Типовые ограничения для всех экземпляров семейства типов
Полагаю, что я хочу, невозможно без Template Haskell, но я все равно спрошу.
У меня есть интерфейс для таких типов, какData.Set
а такжеData.IntSet
:
type family Elem s :: *
class SetLike s where
insert :: Elem s -> s -> s
member :: Elem s -> s -> Bool
...
type instance Elem (Set a) = a
instance Ord a => SetLike (Set a) where
...
И у меня есть семейство типов, которое выбирает оптимальную реализацию набора:
type family EfficientSet elem :: *
type instance EfficientSet Int = IntSet
type instance EfficientSet String = Set String -- or another implementation
Есть ли способ гарантировать, чтоEfficientSet
экземпляры будут всегдаSetLike
и этоElem (EfficientSet a)
являетсяa
?
Без этой гарантии все сигнатуры функций будут выглядеть так:
type LocationSet = EfficientSet Location
f :: (SetLike LocationSet, Elem LocationSet ~ Location) => ...
Писать каждый разSetLike LocationSet
несколько терпимо, ноElem LocationSet ~ Location
делает понимание кода только сложнее, чем для меня.