2

sous-typage structurel en flux peut entraîner une perte d'information:La perte d'information du flux est-elle associée au sous-typage structurel inhérent à ce type de polymorphisme?

type O = {x: number, y: number}; 
type P = {x: number, y: number, z: number} 

function f(o: O) { 
    return o.x * 2, o.y * 2, o; 
} 

const p: P = {x: 2, y: 3, z: 100}; 
const r = f(p); 

r.z // type error (property not found) 

(.. Ce code est terrible, car il effectue des mutations visibles Il est à titre indicatif seulement)

J'ai lu que le polymorphisme de la ligne est un concept pour éviter cette perte d'information sans compromettre la sécurité du type.

Existe-t-il un moyen d'obtenir le même résultat avec un polymorphisme de sous-type?

[EDIT]

Pour répondre à un public plus large que je fournis une brève explication de la terminologie un peu effrayant:

  • Polymorpishm est juste un mot de fantaisie pour déterminer si deux types sont équivalents c'est-à-dire qu'il rend un système de type rigide plus flexible
  • Le polymorphisme paramétrique (génériques en flux) indique que deux types sont toujours équivalent, car les types n'a pas d'importance du tout
  • polymorphisme Sous-type (sous-typage en flux) indique que deux types sont équivalents si vous pouvez obtenir une hiérarchie d'eux, à savoir subsumer le sous-type sous son supertype
  • polymorphism Row est similaire à sous-typage, mais résout le problème de perte d'information (sur le plan technique, cependant, il n'y a pas de relation de sous-type plus, il est donc pas une forme de sous-typage)
  • polymorphism borné stipule que deux types sont équivalents à un but précis seulement, par exemple égalité, ordre, mapping-over etc.

Répondre

2

Pour ce que j'ai lu à propos de Flowtype, je suis à peu près sûr que votre fonction est le problème.

Si vous faites cela à la place:

function f<T: O>(o: T): T { 
    o.x *= 2; 
    o.y *= 2; 
    return o; 
} 

r.z; // okay 

Cela fonctionne en raison du polymorphisme borné. Maintenant, le type de corps vérifie sous l'hypothèse que T est un sous-type de O. En outre, aucune information n'est perdue entre les sites d'appel. En outre, je n'avais pas entendu parler de polymorphisme de ligne avant, donc je suis allé et j'ai cherché. Tout en le regardant, j'ai lu plusieurs choses qui semblent indiquer que le polymorphisme de ligne n'est pas sous-typage. 1, 2, 3.

Pour développer cette réponse et clarifier pourquoi la fonction OP ne fonctionne pas mais celle que j'ai proposée fonctionnera correctement. T his is a nice reference as well but is specific to Java.

En ayant la fonction:

function f(o: O) { 
    return o.x * 2, o.y * 2, o; 
} 

La fonction précise qu'il est à la recherche de façon explicite pour un objet de type O, au lieu d'un objet de O ou d'un sous-type O est autorisé.Dans la fonction OPs, nous descendons le paramètre o vers le type O, plutôt que d'utiliser un générique (c'est mauvais). La bonne façon de gérer cela en utilisant les génériques de préciser qu'il peut être de type O ou sous-type de O, qui peut être fait comme suit:

function f<T: O> (o: T): T { 
    o.x *= 2; 
    o.y *= 2; 
    return o; 
} 

Check out the docs on how flow handles generics et comment il est lié aux paramètres de la fonction, objet, etc. .

la partie pertinente est:

  • « génériques vous permettent de tenir sur le type plus spécifique, tout en ajoutant une contrainte Dans ce type voie sur les médicaments génériques servent. « limites ».

  • « Génériques vous permettent parfois de passer dans les types de tels arguments à une fonction. Ceux-ci sont connus comme génériques paramétrés (ou polymorphisme paramétrique). » link

+0

Pourquoi ma fonction le problème? Il repose uniquement sur la promesse de sous-typage que l'on peut passer dans un sous-type où son supertype est attendu. Votre conseil est plutôt d'utiliser le polymorphisme borné, ce qui signifie simplement que le sous-typage est inférieur à d'autres formes de polymorphisme - du moins dans certains cas et dans la complexité nécessaire pour implémenter un algorithme fiable .. – ftor

+0

@ftor Je comprends ce que vous dites , et il semble que ça marche, mais avec la fonction que vous avez, vous dites qu'il recherche explicitement un param de type O, plutôt qu'un param de type O _ou_ un sous-type de O. Spécifier que le param est vous dites au compilateur que vous attendez un param qui sera de type O ou de sous-type O. Découvrez comment Java le gère https://softwareengineering.stackexchange.com/questions/227918/java-use-polymorphism-or-bounded -type-parameters – kyle

+0

@ftor Checkout ma réponse mise à jour car elle explique mieux mon commentaire précédent et OOP mais dans le contexte de flux. – kyle