Les classes de types sont également une forme de sous-typage.
Ils ne le sont pas. Par souci d'illustration, nous allons revenir à la TypeScript examples je faisais allusion dans cette question:
Si nous avons une valeur qui a un type d'union, nous ne pouvons membres d'accès qui sont communs à tous les types dans l'Union .
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getSmallPet(): Fish | Bird {
// ...
}
let pet = getSmallPet();
pet.layEggs(); // okay
pet.swim(); // errors
Ici, le type de retour de getSmallPet
est ni Fish
ni Bird
, mais un supertype des deux qui a comme membres les membres communs aux deux Fish
et Bird
. Un Fish
est également un Fish | Bird
, et il en est ainsi un Bird
.
Que se passe avec des classes de type est tout à fait différent:
foo :: Num a => a -> a
foo x = (x * x) + x
Bien que les deux foo (3 :: Integer)
et foo (7.7 :: Double)
travail, cela ne signifie pas qu'il y ait un supertype correspondant à Num
que (3 :: Integer)
et (7.7 :: Double)
aussi ont. Plutôt, tout ce que Num a => a -> a
dit est que votre choix de a
devrait avoir une instance de Num
(et il est intéressant de souligner que Num
n'est pas un type), de sorte qu'il existe des implémentations appropriées de (*)
et (+)
pour votre type choisi. Contrairement aux méthodes OOP, (*)
et (+)
n'appartiennent à aucun type particulier, et il n'est donc pas nécessaire d'introduire un supertype afin de les utiliser avec Integer
et Double
.
Je dirais que Haskell n'a pas de sous-typage comme il serait traditionnellement défini car chaque valeur a exactement le type _one_. Typeclasses sont simplement un moyen d'étendre le langage des types pour permettre le polymorphisme défini par l'utilisateur. C'est-à-dire, il laisse une valeur 'x' avoir un type' C a => a' où 'C' est un ensemble de règles' a' qui doit être conforme; mais toujours 'x' a exactement un type. Comparez ceci avec le sous-typage OOPy où une valeur 'x' a plusieurs types: son type de base, et tout type qui subclasse du type de base. – hao
Un autre argument plus pédant: le sous-typage inhiberait l'inférence de type principal de type DHM que possèdent les compilateurs Haskell, contrairement aux typeclasses. – hao
Pour approfondir le point de @ haoformayor: ne pas confondre le sous-typage et le polymorphisme ad-hoc. Le sous-typage est une caractéristique du polymorphisme ad-hoc, et les classes de types sont plutôt différentes. –