2015-10-16 10 views
7

Das erste Beispiel findet erfolgreich die implizite Umwandlung in das Verfahren foo(String) aber sobald ich einen Typ-Parameter (siehe fails) in dem compiliert es nicht mehr beheben:Warum schlägt die implizite Scala-Auflösung für eine überladene Methode mit dem Typparameter fehl?

object works { 
    class A { 
    def foo(): String = ??? 
    } 
    implicit class PimpedA(a: A) { 
    def foo(i: String): String = ??? 
    } 
    val a = new A() 
    a.foo("test") //compiles 
} 

object fails { //same as `works`, but adds type parameter 
    class A { 
    def foo[T](): String = ??? 
    } 
    implicit class PimpedA(a: A) { 
    def foo[T](i: String): String = ??? 
    } 
    val a = new A() 
    PimpedA(a).foo("test") // compiles 
    a.foo("test") // error: too many arguments for method foo:()String 
} 

Dieses Verhalten ist für Scala 2.11.7 und 2.12.0-M3.

Die Dokumentation zu implicits scheint das nicht zu decken und ich genau diesen Fall nicht auf Stackoverflow finden.

Beachten Sie, dass es mein Ziel, die Methode zu überlasten ist foo - wenn ich es umbenennen, der Compiler es findet.

http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

+0

Warum verwenden Sie den gleichen Namen 'foo' für die kuppelte ein? Vielleicht ist es offensichtlich, aber wenn Sie es 'bar' nennen, manifestiert sich der Fehler nicht –

+0

Ich weiß, aber ich will' foo' überladen - ich habe gerade die Frage aktualisiert. –

Antwort

1

beiden Fällen scheinen unter diesem Fall von the specification zu fallen:

Ansichten angewendet werden in drei Situationen:

...

In einer Auswahl e.m(args) mit e vom Typ T, wenn der Selektor m einige Mitglieder bezeichnet von T, aber keines dieser Elemente ist auf die Argumente args anwendbar. In diesem Fall ist eine Ansicht v wird durchsucht, die zu e anwendbar ist und dessen Ergebnis enthält eine Methode, die margs anwendbar ist. Die Suche erfolgt wie bei impliziten Parametern, wobei der implizite Gültigkeitsbereich der von T ist. Wenn eine solche Ansicht gefunden wird, wird die Auswahl e.m in v(e).m(args) konvertiert.

So sollte es funktionieren. Ich war wirklich überrascht, es zu sehen, weil ich noch nie in den Arbeitsfall hineingelaufen bin und angenommen habe, dass es keine implizite Suche gibt, wenn T Mitglieder mit dem Namen m hat. Ich habe einen kurzen Blick auf http://issues.scala-lang.org/ geworfen, konnte aber kein relevantes Problem finden.

+0

Danke Alexey. Ich habe ein Problem auf der scala-lang jira erstellt: https://issues.scala-lang.org/browse/SI-9523 –

+0

typer Debug-Ausgabe: https://gist.github.com/echojc/750ba177f88f4e81d2d0 –

Verwandte Themen