Suppongo che ciò che voglio sia impossibile senza Template Haskell ma lo chiederò comunque.Vincoli di tipo su tutte le istanze di tipo famiglia
ho un'interfaccia per i tipi come Data.Set
e 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
...
E ho una famiglia tipo che sceglie implementazione set ottimale:
type family EfficientSet elem :: *
type instance EfficientSet Int = IntSet
type instance EfficientSet String = Set String -- or another implementation
C'è un modo per garantire che EfficientSet
casi sarà sempre SetLike
e che Elem (EfficientSet a)
è a
?
Senza questa garanzia tutte le firme funzione sarà simile a questo:
type LocationSet = EfficientSet Location
f :: (SetLike LocationSet, Elem LocationSet ~ Location) => ...
Per scrivere ogni volta SetLike LocationSet
è un po 'tollerabile, ma Elem LocationSet ~ Location
rende il codice più difficile la comprensione solo, per quanto mi riguarda.
Davvero? Una dichiarazione di sinonimo 'type' può definire non solo un sinonimo di tipo, ma un sinonimo di tipo vincolo? Interessante. Funziona anche con vincoli di tipo di parametro implicito? –
@JeffBurdges Sì: http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/constraint-kind.html –