Veuillez considérer est-il possible pour le compilateur d'infère J'ai ce sentiment que je suis négligeant quelque chose d'embarcence simple ici;) p> EDIT: je viens de découvrir qu'utilisant un autre paramètre type peut-il s'il vous plaît expliquer cela à moi? est-ce un problème d'unification? strong> p> EDIT 2: Utilisation de Classe de la case FOO [A, B <: liste [a]] (L: B) {...} code> ou quelque chose d'appartement. En particulier, a code> ainsi que B code> doit être disponible quelque part dans le corps de FOO code>. A code> automatiquement? Par exemple, foo (liste (1,2,3)) code> échoue car le vérificateur de type infère A code> comme rien code>. Peut-être qu'il y a un moyen en utilisant des membres de type pour résoudre ce problème? P> x code> fonctionne juste bien, mais guichet automatique Je ne comprends pas pourquoi c'est le cas: p> [A, B [x] <: liste [x]] (L: B [A]) / code> peut avoir des implications indésirables pour certaines hiérarchies (bien que ce ne soit pas vraiment une grosse affaire). Plus de conclusions intéressant, je viens de tomber sur un publication du blog par Josh SUERETH Cela montre implicitement que [a, b <: liste [a]] (L: B avec la liste [A]) code> fonctionne aussi bien ... pas besoin de implicite, etc. p> < / p>
3 Réponses :
Cela ne répond pas vraiment à la partie "Pourquoi", désolé, mais voici quelques astuces supplémentaires que vous pouvez jouer. Tout d'abord, puisque vous n'utilisez pas le puis: p> (J'utilise le covariant in action: p> ... et vous obtenez Les paramètres de type x code> dans votre exemple, vous pouvez écrire: SEQ code> au lieu de Liste code> pour montrer qu'il fonctionne également pour les sous-types. Aussi, notez que cela ne correspond pas à l'utilisation du supplément x code>, voir les commentaires.) Malheureusement, chaque fois que vous souhaitez utiliser le type de séquence, vous devez écrire b [a] code>, c'est-à-dire l'instancier manuellement. Une façon de contourner cela consiste à écrire à la place: p> a code> et b code> instancié comme si vous saviez toujours qu'ils devraient. p> p>
C'est mauvais conseil. N'écrivez jamais "B [] <: SEQ [ I>]", cela ne signifie pas ce que vous pensez. Il utilise effectivement le X, pour lier le paramètre de type B de B sur SEQ. Les soulignés dans "B [] <: SEQ [ I>]" ne sont pas le même type.
Outre le problème _ code>, j'ai trouvé cela dans un poste intéressant car je n'aurais jamais deviné qu'une vue implicite pourrait aider. Alors, où le compilateur trouve-t-il une vue implicite pour B code> comme SEQ [A] code>? Lorsque j'ai essayé dans la console, il a trouvé une fonction de Predef, mais cela fonctionne également avec des classes personnalisées (apparemment, il n'est pas possible d'avoir des exemples joliment formatés dans cette section, désolé). Y a-t-il un moyen de suivre ce qui implique le compilateur tire?
Ah, ok, en regardant la source de PreDef révèle l'infrastructure de <: <, =: = et <% <.
Désolé, cette première partie n'était pas si claire. Ils ne sont vraiment pas équivalents, et b [_] <: SEQ [_] code> est vraiment b [x] foresome {type x; } <: SEQ [Y] FORSOME {TYPE Y; } code>. Mon point était, dans ce cas i> Peu importe ce que le célibataire x code> ou les deux existentiels _ code> s est attribué, parce que vous ne voulez jamais Utilise les. Pour tout ce que vous savez x code> est affecté au joli inutile tout code> et mes deux existentielles à rien code> et tout code> respectivement , mais b [a] code> est ce qui compte à la fin.
Il n'est pas possible que le compilateur infère automatiquement. Mais si cela était possible, il faudrait dire que cela devrait être un Superype em> de Int, donc int ou tout, pas seulement int! Int!. Parce qu'une liste [int] <: liste [tout]. Donc, si le compilateur déduirait Int pour un ce serait trop restrictif. p>
En d'autres termes: P>
Case (2) ne laisse aucune place à un autre que Int.
Case (1) Cependant, laisse la place pour être quelque chose d'autre que INT, par ex. Cela pourrait être tout.
Vous pouvez voir cela parce que vous pourriez l'appeler par Les deux cas ne sont pas équivalents. p>
Classe de la case FOO [A, B <: liste [A]] (L: B) {...} code>
puis l'appelant comme foo (liste (1,2,3)) code> Vous dites que un type doit être un type pour lequel une liste devrait être une super-équipée d'une liste de la liste des Int em>.
Donc, efficacement, un super-espèce d'int car la liste est Covariant. P> Li>
Barre de la classe [A, B [x] <: liste [x]] (L: B [A]) code>
et ensuite l'appelant comme foo (liste (1,2,3)) code> vous dites que un doit être un int em>. p> li>
ol>
foo [tout, liste [int]] (liste (1,2,3)) code>. Vous ne seriez pas capable de le faire au cas où (2). P>
Merci, que foo [Tout, liste [int]]]] code> est un bon. Otoh, je me demande pourquoi, à la suite de votre raisonnement, il est toujours impossible de dire quelque chose comme foo [a, b>: liste [a] <: liste [a]] code> parce que ce serait, d'une logique point de vue, retirez l'ambiguïté (ou n'est-ce pas, je me demande?). Pourtant, dans les deux cas, c'est-à-dire que ce dernier ainsi que celui mentionné dans mon poste d'origine, le compilateur déduit A code> comme rien code> et continue de se plaindre de cela (compréhensible de mon point limité de la vue) C'est pourquoi je pense que outre la question de la covariance, cela peut également être expliqué en termes d'unification?
Oui en effet, je suis votre raisonnement. Je suppose que c'est ce que l'on entend avec le type de type Scala est incomplet.
Il y a ce très sympa Talk de Daniel SpoWack sur (non seulement Scala's) Inférence de type incomplète. L'intro est assez longue mais toute la conversation en vaut la peine.
A annexé une nouvelle "perspicacité" à mon message d'origine, juste au cas où vous êtes intéressé.
Selon Alexey Romanov , en principe, le type pourrait être déduit automatiquement mais tout simplement pas à l'époque. p>
Donc, au moins pour l'instant, tous les paramètres de type qui doivent être déduits doivent apparaître explicitement dans les arguments. P>
Pouvez-vous définir la classe comme
Classe de cas FOO [A] (L: liste [A]) code>? Cela pourrait être plus clair.Je comprends ce que vous voulez dire, mais ce n'est pas applicable dans mon scénario. Les deux types A et B doivent être connus les uns des autres.