Ограничения типов для всех экземпляров семейства типов

Полагаю, то, что я хочу, невозможно без 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 только усложняет понимание кода, как по мне.

9
задан modular 7 March 2012 в 09:35
поделиться