2017-02-25 4 views
4

J'essaie de comprendre les différences entre les classes de type et GADTS, en particulier lorsque vous utilisez l'extension -XMultiParamTypeClasses.Comprendre quand utiliser des classes de types ou des GADT?

Les deux semblent avoir des utilisations similaires:

class MyClass a b where 
    f :: a -> b -> Bool 

instance MyClass String String where 
    f s1 s2 = ... 

instance MyClass Int Int where 
    f i1 i2 = ... 

data Gadt a where 
    F :: String -> String -> Bool 
    F2 :: Int -> Int -> Bool 

Jusqu'à présent, la seule différence que je vois vraiment que permettre de GADT une interface de type fonction d'avoir un des arguments de nombre flexibles:

data Gadt a where 
    PassTwoArgs :: String -> String -> Gadt Bool 
    PassOneArgs :: String -> Gadt Bool 

myFunction :: Gadt a -> a 
myFunction (PassTwoArgs s1 s2) = ... 
myFunction (PassOneArgs s1) = ... 

Alors que Ce n'est pas facile avec les classes de types.

Existe-t-il d'autres différences ou cas d'utilisation pour utiliser l'un sur l'autre?

Répondre

6

Si vous avez une classe , vous pouvez ajouter de nouvelles instances à tout moment.

Si vous utilisez un GADT, vous avez une structure de données qui est fixée pour toujours. Vous ne pouvez jamais ajouter de nouveaux cas, sans modifier la définition d'origine. Cependant, comme vous le constatez, c'est beaucoup plus flexible. Vraiment, ils sont destinés à différents cas d'utilisation. Les classes sont pour quand vous voulez être capable de faire quelque chose à beaucoup de types de données différents qui n'ont rien à faire les uns avec les autres. (Par exemple, vous pouvez faire (==) sur Int et sur String, mais ces types ne sont pas très similaires.) GADT sont pour quand vous voulez avoir un type, mais certains de ses paramètres de type vous dire quelque chose à ce sujet. L'exemple canonique est où le GADT représente une expression dans un langage de programmation, et vous voulez utiliser le système de type Haskell pour appliquer le système de type de l'autre langue.

Quelles classes ne sont pas comme sont les «classes» que nous utilisons dans la programmation orientée objet. ;-) S'il vous plaît mettez toutes ces idées hors de votre cerveau.

2

Si vous avez besoin d'un modèle, utilisez un ADT (G). Si vous avez besoin de tiers pour implémenter votre interface, utilisez une classe de types.

Mon intuition est d'utiliser autant que possible les typeclasses; Si j'ai absolument besoin d'un modèle, alors je vais chercher un (G) ADT. D'habitude, je n'en ai pas besoin.