18

Dans ce PDF presentation sur les classes Haskell type, diapositive no 54 a cette question:Génériques et Constrained Polymorphisme contre sous-typage

Question ouverte:

Dans une langue avec les génériques et polymorphisme contrainte, faire vous avez également besoin du sous-typage ?

Mes questions sont les suivantes:

  1. Comment les médicaments génériques et faire du polymorphisme contraint le sous-typage inutile?

  2. Si les génériques et le polymorphisme contraint rendent le sous-typage inutile, pourquoi Scala at-il un sous-typage?

+2

Vous pourriez être intéressé par Scalaz, qui a largement utilisé le polymorphisme contraint (aka ad-hoc). L'inférence de type dans Scala ne fonctionne pas dans beaucoup d'endroits comme Haskell, ce qui peut compliquer l'encodage de classes de types. Mais nous essayons quand même :) – retronym

Répondre

6

Oleg Kiselyov et "Haskell's overlooked object system" de Ralf Lämmel proposent une bibliothèque pour Haskell qui implémente un système objet utilisant les fonctions existantes de Haskell, y compris les classes de types.

Un extrait de la section « introduction » du papier (Souligné par l'auteur):

L'intérêt pour ce sujet n'est pas du tout réservé aux chercheurs et aux praticiens Haskell car il est une question fondamentale et instable - une question qui est abordée dans le présent document:

              Quelle est la relation entre le polymorphisme de type classe limitée et sous-type?

Dans ce contexte de recherche, nous Plus précisément (et avec insistance) nous limiter à la langage Haskell existant (Haskell 98 et extensions communes le cas échéant), à savoir, pas de nouvelles extensions Haskell doivent être proposées. Comme nous allons le corroborer, cette restriction est adéquate, car elle nous permet de fournir une réponse significative et importante à la question susmentionnée.

+0

C'est exactement ce que je cherchais il y a> 2 ans. :-) – missingfaktor

+0

On dirait que le développement sur OOHaskell est encore assez actif: https://github.com/nkaretnikov/OOHaskell –

14

Eh bien, si c'est effectivement une question ouverte, alors par définition, nous ne connaissons pas la réponse à # 1. Les espaces de conception sont assez différents, et il n'est pas évident pour moi de savoir comment vous pourriez encoder directement le sous-typage en polymorphisme contraint. Le codage est direct lorsque les arguments sont polymorphes. Par exemple, une fonction Haskell avec le type

foo :: (Num a) => a -> Bool 

équivaut à, dire:

Bool foo(Num x) 

dans un langage OO. Cependant, il ne sait pas comment coder:

// I will return some Num, but I'm not going to tell you what kind exactly 
Num bar(Bool x) 

dans le polymorphisme contraint, ni clairement comment coder:

-- I can return any kind of Num, *you* tell *me* what kind 
bar :: (Num a) => Bool -> a 

en sous-typage. Ma meilleure estimation pour # 2 est que Scala doit parler à Java, et Java parle de sous-typage. Et parce que Scala a toutes les caractéristiques du système de type connu de l'homme parce qu'il pense qu'il doit être cool. :-P

+4

Dans Haskell, vous pouvez toujours obtenir un comportement OO (renvoyant un pointeur vers un objet abstrait) en ajoutant 'data ANum = forall a.(Num a, NumCoerce a) => ANum a' – ony

+0

Pour "Je peux retourner n'importe quel type de Num, * vous * dites * moi * quel genre" sur la variante "Num bar (Bool x, NumFactory f)' (bien sûr cela peut parfois mener à la conversion de 'Num' en type réel produit par' f') – ony

+0

Si le polymorphisme de rang 2 est autorisé, vous pouvez exprimer "Num bar (Bool x)" comme "Bool -> (forall n. => n -> a) -> a " – Martijn

5

2 est facile: parce que Java (et bytecode JVM) l'a. Si nous voulons utilement appeler Scala à partir de Java, nous devons à peu près permettre l'extension des interfaces et des classes Java; et si les classes Scala sont traduites en classes JVM (et traits en interfaces), alors nous pouvons les étendre aussi.

La même raison pour laquelle Scala a null :)

Quant à 1, vous devez également avoir des types existentiels pour coder le

Num bar(Bool x) 

cas:

bar :: Bool -> exists a. Num a 
29

Comment les génériques et le polymorphisme contraint rendent-ils le sous-typage inutile?

On ne sait pas ce qu'ils font. Si vous mettez la diapositive dans le contexte, je pense que l'argument du locuteur essaie de faire quelque chose comme ça va:

  • Dans l'ancien temps, le sous-typage fourni une sorte de polymorphisme importante.

  • Autrefois, dans un autre pays, l'abstraction de type et les paramètres de type fournissaient un type important de polymorphisme. Ce type est connu dans son pays natal comme polymorphisme paramétrique, mais dans les pays étrangers, il est appelé génériques. Les génériques modernes admettent des contraintes, parfois appelées "polymorphisme borné", qui peuvent accomplir beaucoup de choses du même type que le polymorphisme de sous-type. En particulier, vous devez vous soucier de la covariance et de la contravariance. Les langues se terminent par des restrictions désagréables, des notations de poids lourds et parfois des violations de sécurité directes (par exemple, Eiffel).

La question ouverte: peut-être contraint paramétrique polymorphes résout assez des mêmes problèmes que dans l'avenir heureux, nous pouvons nous débarrasser du polymorphisme du sous-type tout à fait, et avec elle la question désagréable quand le sous-typage est covariant, contravariant et invariant.