J'ai une fonction avec deux listes de paramètres que j'essaye de s'appliquer partiellement et d'utiliser avec Currying. La deuxième liste de paramètres contient des arguments qui ont toutes des valeurs par défaut (mais pas implicites). Quelque chose comme ceci: MAINTENANT, ce qui suit est bien: p> maintenant si je définis: p> class Test2(val a: Int) {
def apply(b: Int = 2, c: Int = 3) { println(a + ", " + b + ", " + c); }
}
def test2(a: Int) = new Test2(a);
def partial2 = test2(1); // Note no underscore
test2(1)(2, 3);
test2(1)(2);
test2(1)(c=3);
test2(1)();
partial2(2, 3)
partial2(2);
partial2(c=3);
partial2();
3 Réponses :
Le moteur d'inférence de type donne à Pour résoudre ce problème, vous devez définir peut-être que vous voudrez peut-être facturer les valeurs par défaut où les deux partiel code> le type de ce qui vient ensuite; I.e., l'expansion de l'ETA
Test (1) _ code>. Vous pouvez voir par ex. Dans la région, que
partiel code> a type
(int, int) => unité code>, alors que
test code> a type
(A: int) ( B: INT, C: INT) unité code>. Le résultat de l'expansion ETA est une fonction code> code>, qui ne porte aucun nom d'argument avec celui-ci (car il est possible de définir la fonction
code> avec des paramètres anonymes).
partiel code> comme suit: p>
Test code> et
partiel code> peut les atteindre pour s'assurer qu'ils restent égaux. Mais je ne connais aucun truc pour éviter de répéter les noms des paramètres sans introduire des frais généraux supplémentaires comme la création de nouveaux objets, etc. P> P>
L'objet code> fonction code> contient des noms d'arguments, mais ce sont les noms d'arguments définis dans Fonction2 code> Vous pouvez réellement appeler l'exemple donné par @desperate de cette façon:
partial (V1 = 2, v2 = 3) code>.
Je pensais que cela fallait faire avec le compilateur ne créant pas de nouvelles classes pour des fonctions telles que celles-ci mais en utilisant la fonction "générique "2 à la place. Sinon, cela aurait pu stocker toutes les informations dont il a besoin dans les annotations. Tout le point était d'éviter de répéter des noms d'arguments / liste, cependant :(
@Moritz, je me rends compte que, mais ce n'est pas utile du tout quand on veut préserver des noms appropriés. Ceci est vraiment une déficience si ce n'est pas un défaut de la langue. Je n'ai jamais compris pourquoi Scala tente de réutiliser la fonction pré-créée
@Desperate Je n'ai pas dit que c'était utile - cela pourrait même être nocif si vos paramètres avaient les mêmes noms dans un ordre différent. Scala génère en fait une sous-classe de des cas de fonctionnement code> comme ceci, mais qui renvoie un sous-type spécialisé ici ferait une surcharge assez délicate.
C'est le meilleur que je puisse faire moi-même jusqu'à présent: CLASS TEST2 (VAL A: INT) {DEF Appliquer (B: INT = 2, C: INT = 3) {PrintLN (A + "," + B + "," + c); }} def test2 (A: int) = nouveau test2 (a); DEF partielle2 = Test2 (1); // NOTE Aucun test de soulignement2 (1) (2, 3); Test2 (1) (2); test2 (1) (c = 3); test2 (1) (); partielle2 (2, 3) partielle2 (2); partielle2 (c = 3); partielle2 (); De cette façon ça marche ...
@ Désespéré / @ apprenant cool! Veuillez le poster comme une réponse aussi, ce sera plus lisible.
Je veux ... mais je ne suis pas encore autorisé (moins de 24h puisque j'ai posté la question)
Suivi de votre commentaire, voici un moyen plus compact pour l'écrire:
java.lang.Object{def apply(b: Int,c: Int): Unit; def apply$default$1: Int @scala.annotation.unchecked.uncheckedVariance; def apply$default$2: Int @scala.annotation.unchecked.uncheckedVariance}
C'est le meilleur que je puisse faire moi-même jusqu'à présent: de cette façon fonctionne ... p> p>
permalink.gmane.org/gmane.comp.lang.scala.user/ 36288