56 votes

Pourquoi n'y a-t-il pas beaucoup de discussions sur la co- et la contre-variance en Haskell (par opposition à Scala ou C#) ?

Je sais ce que sont la covariance et la contravariance des types. Ma question est la suivante : pourquoi n'ai-je pas encore rencontré de discussion sur ces concepts dans mon étude de Haskell (par opposition à Scala, par exemple) ?

Il semble qu'il y ait une différence fondamentale dans la façon dont Haskell considère les types par rapport à Scala ou C#, et j'aimerais articuler cette différence.

Ou peut-être que je me trompe et que je n'ai pas encore appris suffisamment de Haskell :-)

60voto

C. A. McCann Points 56834

Il y a deux raisons principales :

  • Haskell n'a pas de notion inhérente de sous-typage, donc en général la variance est moins pertinente.
  • La contravariance apparaît principalement lorsque la mutabilité est impliquée, donc la plupart des types de données en Haskell seraient simplement covariants et il y aurait peu d'intérêt à le distinguer explicitement.

Cependant, les concepts s'appliquent - par exemple, l'opération de levage réalisée par fmap para Functor est en fait covariante ; les termes co/contravariance sont utilisés en théorie des catégories pour parler des foncteurs. Le site contravariant paquet définit une classe de type pour les foncteurs contravariants, et si vous regardez la liste des instances, vous verrez pourquoi j'ai dit que c'était beaucoup moins courant.

Il y a aussi des endroits où l'idée apparaît implicitement, dans la façon dont les conversions manuelles fonctionnent - les différentes classes de types numériques définissent les conversions à partir de et vers des types de base tels que Integer y Rational et le module Data.List contient des versions génériques de certaines fonctions standard. Si vous regardez les types de ces versions génériques vous verrez que Integral contraintes (donnant toInteger ) sont utilisés sur les types en position contravariante, alors que Num contraintes (donnant fromInteger ) sont utilisés pour la position covariante.

21voto

dflemstr Points 18999

Il n'y a pas de "sous-types" en Haskell, donc la covariance et la contravariance n'ont aucun sens.

En Scala, vous avez par exemple Option[+A] avec les sous-classes Some[+A] y None . Vous devez fournir les annotations de covariance + pour dire qu'un Option[Foo] est un Option[Bar] si Foo extends Bar . En raison de la présence de sous-types, cela est nécessaire.

En Haskell, il n'existe pas de sous-types. L'équivalent de Option en Haskell, appelé Maybe a cette définition :

data Maybe a = Nothing | Just a

La variable de type a ne peut être qu'un seul type, il n'est donc pas nécessaire de fournir d'autres informations à son sujet.

7voto

Hans Points 936

Comme mentionné, Haskell n'a pas de sous-types. Cependant, si vous vous intéressez aux classes de types, il se peut que vous ne compreniez pas comment cela fonctionne sans sous-typage.

Les classes de type spécifient des prédicats sur les types, pas les types eux-mêmes. Ainsi, lorsqu'une classe de type a une superclasse (par exemple Eq a => Ord a), cela ne signifie pas que les instances sont des sous-types, car seuls les prédicats sont hérités, pas les types eux-mêmes.

De même, les termes covariant, contravariant et in-variant ont des significations différentes dans différents domaines des mathématiques (voir Wikipedia). Par exemple, les termes covariant et contravariant sont utilisés dans les foncteurs (qui sont à leur tour utilisés dans Haskell), mais ces termes ont une signification complètement différente. Le terme invariant peut être utilisé à de nombreux endroits.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X