2013-06-14 5 views
24

J'ai quelques difficultés à comprendre lors de l'utilisation et quand ne pas utiliser typeclass dans mon code. Je veux dire créer mon propre, et non utiliser déjà défini typeclasses, bien sûr. Par exemple (exemple très stupide), dois-je faire:Devrais-je utiliser des typeclasses ou non?

data Cars = Brakes | Wheels | Engine 
data Computers = Processor | RAM | HardDrive 

class Repairable a where 
    is_reparaible :: a -> Bool 

instance Repairable Cars where 
    is_repairable (Brakes) = True 
    is_repairable (Wheels) = False 
    is_repairable (Engine) = False 

instance Repairable Computers where 
    is_repairable (Processor) = False 
    is_repairable (RAM)  = False 
    is_repairable (HardDrive) = True 

checkState :: (Reparaible a) => a -> ... 
checkState a = ... 

(Évidemment, ceci est un exemple stupide, incomplète).

Mais c'est beaucoup pour une petite utilisation, non? Pourquoi je ne devrais pas faire quelque chose de simple et seulement définir des fonctions sans définir de nouveaux types de données et typeclasses (avec leurs instances).

Cet exemple est trop simple, mais en fait, je vois souvent des choses comme ça (nouveaux types de données + typeclasses + instances) quand je parcours le code Haskell sur github au lieu de définir uniquement des fonctions. Donc, quand je devrais créer de nouveaux types de données, typeclasses etc et quand devrais-je utiliser des fonctions?

Merci.

Répondre

40

Pourquoi je ne devrais pas faire quelque chose de simple et seulement définir des fonctions sans définir de nouveaux types de données et (avec leurs classes de types cas).

Pourquoi en effet? Vous pouvez simplement définir:

checkState :: (a -> Bool) -> (a -> b) -> (a -> b) -> a -> b 
checkState is_repairable repairs destroy a 
    = if (is_repairable a) then repairs a else destroy a 

Les utilisateurs abusent des classes de types tout le temps. Cela ne veut pas dire que c'est idiomatique.

Pour répondre à votre question plus générale, voici quelques règles de base pour savoir quand utiliser des classes de type et quand ne pas les utiliser:

classes de type Utiliser si:

  • Il n'y a qu'un seul comportement correct par type donné

  • La classe de type a associé les équations (ie "lois") que toutes les instances doivent satisfaire

Ne pas utiliser les classes de type si:

  • Vous essayez de juste des choses d'espace de noms. C'est à ça que servent les modules et les espaces de noms.

  • Une personne qui utilise votre classe de type ne peut pas raisonner sur la façon dont il se comportera sans regarder le code source des instances

  • Vous trouvez que les extensions que vous devez activer sont hors de contrôle

+0

Ouais! C'est une réponse très complète, merci beaucoup! Votre "ne pas utiliser les classes de caractères si ..." sera particulièrement utile pour choisir la bonne façon de faire quelque chose. – vildric

+1

Je voudrais ajouter à cela "ne pas utiliser typeclasses juste pour une méthode", même si ce n'est pas une règle absolument rigide, plus comme un indice général. – MathematicalOrchid

+2

@MathematicalOrchid Cela fait en quelque sorte partie de la règle des "besoins" puisque vous aurez rarement des lois pour une classe de type avec une seule méthode (à l'exception de "SemiGroup", où vous avez la loi d'associativité) –

5

Vous pouvez souvent utiliser un type de données au lieu d'une classe de type, par exemple

data Repairable a = Repairable 
    { getRepairable :: a 
    , isRepairable :: Bool 
    , canBeRepairedWith :: [Tool] -> Bool -- just to give an example of a function 
    } 

Bien sûr, vous devez transmettre cette valeur explicitement, mais cela peut être une bonne chose si vous avez plusieurs choix (pensez par exemple de Sum et Product que possible Monoid s pour les nombres). Sauf que vous avez plus ou moins la même expressivité que pour une classe-type.

+2

Je ne suis pas le downvoter, mais. . . cette réponse ne répond pas vraiment à la question à mon humble avis. L'OP demande quand typeclasses doit être utilisé. Cette réponse mentionne une alternative aux typeclasses, mais ne dit pas quand utiliser cette alternative. (Si quelque chose, il semble * présupposer * une compréhension du moment où les typeclasses ont un sens, et offre une alternative qui a du sens dans plusieurs des mêmes cas.) – ruakh

Questions connexes