2016-12-13 3 views
3

Est-il possible de spécifier que chaque membre d'un datakind satisfait une classe de type, de sorte que la contrainte de classe est implicite? Par exemple.Type de classe instancié sur chaque valeur d'un type de données

data AB = A | B 
class Foo (a :: AB) where get :: proxy a -> String 
instance Foo A where get _ = "A" 
instance Foo B where get _ = "B" 

-- note lack of constraint here 
get' :: proxy (a :: AB) -> String 
get' = get 

Fondamentalement a est un AB donc nous sommes sûrs qu'il ya une instance de Foo pour elle. Je le trouve improbable - où va-t-il obtenir le dictionnaire Foo? - Mais j'ai vu de la magie dans ma journée.

+0

J'ai fermé cela comme un double de http://stackoverflow.com/questions/32408110/datakinds-and-type-class-instances mais rouverte. La classe séparée 'Foo' contrainte à fonctionner uniquement sur' AB' pourrait laisser place à de la magie que je ne peux pas imaginer. – Cirdec

Répondre

6

Non, vous ne pouvez pas faire cela. Le principal problème est que, comme vous le mentionnez, il n'y a rien pour obtenir un dictionnaire. Mais l'autre problème est que votre affirmation selon laquelle chaque type dans AB est une instance de Foo est faux.

type family Broken :: AB where 
+0

Ou 'GHC.Exts.Any :: AB'. – Alec

+0

Intéressant, je n'avais pas considéré que toutes sortes pouvaient avoir un "fond", ce qui aurait certainement mis un frein aux choses sémantiquement. Il est alors logique de contraindre à des types de forme normale, peut-être avec une classe 'NF k', qui pourrait ensuite être utilisée pour fournir les dictionnaires nécessaires. Hmmm .... de toute façon, merci pour la perspicacité – luqui

+0

@luqui, un singleton fera l'affaire. 'données ABy x où Ay :: ABy 'A; Par :: ABy 'B'. Si vous voulez, 'class KnownAB x où knownAB :: ABy x'. La correspondance de modèle sur 'knownAB' vous permet d'utiliser les instances. – dfeuer