8
votes

Pourquoi Scala ne peut-il pas déduire le paramètre de type dans cet exemple?

Supposons que j'ai deux classes, entrée code> et sortie code>, qui sont conçus pour être connectés les uns aux autres. sortie code> produit des valeurs de type, et entrée code> les consomme. xxx pré>

C'est bon si une entrée code> code> et Sortie CODE> PAIR Ne fonctionne pas sur le même type de valeur tant que le paramètre code> entrée code> est un super-type du paramètre code> de type code>. Notez que le paramètre de type dans les deux classes est invariant; Dans les versions réelles, il est utilisé à la fois dans des positions de co et de contravérie. P>

J'ai une méthode code> code> ailleurs, qui définit un lien entre une entrée code> / sortie code> paire: p> xxx pré>

Si j'appelle cette méthode ci-dessous, je reçois une erreur de type: p>

test.scala:17: error: type mismatch;
 found   : Output[String]
 required: Output[AnyRef]
  connect(out, in)
          ^


2 commentaires

Voulez-vous dire "Ne pas utiliser sur le même type de valeur"


Avez-vous essayé de poser la question à la liste de diffusion Scala?


3 Réponses :


6
votes

Vous obtiendrez parfois de meilleurs résultats si vous utilisez plusieurs listes de paramètres: xxx

... et en fait dans ce cas, cela fonctionne.


2 commentaires

Pouvez-vous développer pourquoi c'est? "Parfois, obtenez de meilleurs résultats" ne semble pas très déterministe!


Malheureusement, le déducteur de type n'est pas spécifié et n'est parfois pas déterministe non plus.



0
votes

Je suis peut-être totalement faux, mais je pense que le problème est que lorsque vous attachez ensemble l'entrée et la sortie: L'entrée a une sortie limitée à un sous-type de T, mais la sortie a une entrée limitée à un super-espèce de T, le seul type pouvant satisfaire les deux conditions est T. xxx

lorsque vous créez L'entrée avec la sortie (remplaçant Q avec _ <: T) vous obtenez: xxx

identique à

entrée [t] -> entrée [ _ <: T <: _]

d'où la désactivation de type


3 commentaires

Dans mon exemple, String et Anyref satisfont mes contraintes. La sortie produit des chaînes et nécessite une entrée qui consomme un super-espèce de chaîne. L'entrée consomme AnyRefs et nécessite une sortie qui produit un sous-type de AnyRef. Puisque la chaîne est un sous-type de AnyRef, les contraintes sont satisfaites.


Le problème est qu'il existe exactement un paramètre de type approprié pour la connexion, et c'est le paramètre de type de la sortie. Lorsque je spécifie cela explicitement, cela fonctionne bien. Si je ne le fais pas, il essaie d'utiliser le paramètre de type de l'entrée et d'obtenir une erreur de type sur l'argument de sortie.


Désolé, j'ai mal interprété l'entrée [_>: T] dans la signature de Connect [t] (



0
votes

En réalité, Scala Type Inferene ne peut pas gérer "Récursion" pour l'instant. Donc, si le type d'argument ne peut être déduit que dans la collocation avec d'autres arguments Scala ne parvient pas à infercer. Mais si vous utilisez DiffNT Argument List Scala F (a) (A) (B) (C, D) déduira les types de types de liste par liste, de sorte qu'il fonctionne de manière utile.

PS Il est trop simplifié, mais peut vous obtenir un indice.


0 commentaires