ambigious implitits

8

Die Frage ist, warum funktioniert der folgende Code nicht mit Typinferenz (unten ist eine REPL-Sitzung zu demonstrieren), und kann es behoben werden? Genauer gesagt, wie unterscheidet sich dies von der Verwendung von CanBuildFrom, von dem der Compiler den Rückgabetyp ableitet?

Gegeben dieser Code:

%Vor%

Ich habe diese Sitzung in der REPL (2.8.1):

%Vor%     
IttayD 22.03.2011, 12:53
quelle

4 Antworten

4
%Vor%     
extempore 22.03.2011, 15:51
quelle
5

Ich kann sehen, warum Sie erwarten, dass es funktioniert, aber offensichtlich verwendet der Inferenztyp den Rückgabetyp nicht, um auf T zu schließen. Ich würde es auch erwarten.

Was die Mehrdeutigkeit anbelangt, vermeidet CanBuildFrom , mehrdeutig zu sein, indem einfach nicht alles auf derselben "Ebene" definiert wird. Zum Beispiel löst dies das Mehrdeutigkeitsproblem:

%Vor%

Allerdings bewirkt nicht , dass die Typrückschlüsse so funktionieren, wie Sie es möchten:

%Vor%

Was darauf hinweist, dass es offensichtlich T Rückschluss macht, ohne den Rückgabetyp zu berücksichtigen.

    
Daniel C. Sobral 22.03.2011 14:43
quelle
2

Bezüglich einer impliziten Mehrdeutigkeit ist die Regel (seit Scala2.8 ) :

  

Beim Vergleich von zwei verschiedenen anwendbaren Alternativen einer überladenen Methode oder einer impliziten Methode:

     
  • erhält einen Punkt für mit spezifischeren Argumenten ,
  •   
  • und ein anderer Punkt für , der in einer richtigen Unterklasse definiert ist .
  •   

Eine Alternative "gewinnt" gegenüber einer anderen, wenn sie in diesen beiden Vergleichen eine größere Anzahl von Punkten erhält.
  Dies bedeutet insbesondere, dass, wenn Alternativen identische Argumenttypen haben, diejenige, die in einer Unterklasse definiert ist, gewinnt.

Ich denke nicht, dass die implicits um URL oder URI nach diesen Kriterien eine andere Menge von Punkten erhalten.

    
VonC 22.03.2011 14:14
quelle
2

Es ist vielleicht nicht offensichtlich aus dem Fehlerbericht, den Sie sehen, aber alle drei implicits, die im Objekt UrlLike definiert sind, tragen zur Ambiguität bei (zB versuchen Sie, die Definition von uri zu kommentieren und Sie werden die Mehrdeutigkeit sehen als zwischen str und url gemeldet).

Der Grund für die Mehrdeutigkeit ist, dass der Typparameter T von UrlSupport.url nur durch die Anforderung beschränkt ist, dass eine implizite UrlLike-Instanz für ihn verfügbar ist. String, URL und URI erfüllen alle diese Anforderung gleichermaßen dank der UrlLike-Instanzen, die von Ihren drei impliziten Objekten bereitgestellt werden. Der Compiler wird keinen von denen für Sie willkürlich auswählen, also meldet er eine Mehrdeutigkeit.

Es sei denn, Sie lösen die Mehrdeutigkeit natürlich, indem Sie das Argument type explizit angeben, wie Sie es in den letzten beiden REPL-Interaktionen getan haben.

    
Miles Sabin 22.03.2011 14:20
quelle

Tags und Links