Przypuszczam, że to, czego chcę, jest niemożliwe bez szablonu Haskella, ale mimo to zapytam.Ograniczenia typu we wszystkich instancjach rodzinnych typów
Mam interfejs dla typów jak Data.Set
i 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
...
I mam rodzinę typu, który wybiera optymalny zestaw realizacji:
type family EfficientSet elem :: *
type instance EfficientSet Int = IntSet
type instance EfficientSet String = Set String -- or another implementation
Czy istnieje sposób, aby zagwarantować, że EfficientSet
instancji będzie zawsze SetLike
i że Elem (EfficientSet a)
jest a
?
Bez tej gwarancji wszystkie podpisy funkcja będzie tak:
type LocationSet = EfficientSet Location
f :: (SetLike LocationSet, Elem LocationSet ~ Location) => ...
Aby pisać za każdym razem SetLike LocationSet
jest dość znośny, ale Elem LocationSet ~ Location
sprawia zrozumienie kodu tylko mocniej, jak dla mnie.
Naprawdę? Deklaracja synonimów typu "type" może definiować nie tylko synonim typu, ale synonim ograniczenia typu? Ciekawy. Czy to działa również z niejawnymi ograniczeniami typu parametru? –
@JeffBurdges Tak: http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/constraint-kind.html –