Sagen, ich habe eine einfache Klasse, wie dieseFolgern Art von generischen impliziten Parameter vom Rückgabetyp
abstract class Foo {
implicit val impInt: Int = 42
def f[A]()(implicit a: A): A
val f2: Int = f()
}
Wenn val erklärt f2
, Compiler in der Lage ist zu folgern, dass die Art der impliziten Parameter der Funktion f
ist Int
, weil das type ist identisch mit dem Ergebnistyp, und der Ergebnistyp muss dem Werttyp f2
entsprechen, der Int
lautet.
Allerdings wirft ein Ordering[A]
in den Mix:
def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()
Ergebnisse in diesem Compiler-Fehler:
Ambiguous implicit values: both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] and method $conforms in object Predef of type [A]=> <:<[A,A] match expected type A
Wenn ich die Typinformationen hinzufügen, wenn f()
Aufruf, es kompiliert:
val f2: Int = f[Int]()
Zuerst stieß ich auf den Fall mit impliziter Reihenfolge ein d Ich dachte, es hat damit zu tun, dass Scala von links nach rechts schließt; Ich dachte, es ist nicht in der Lage, den Rückgabetyp zuerst und dann den (impliziten) Parametertyp von f
abzuleiten. Aber dann habe ich den Fall ohne implizite Bestellung versucht und sah, dass es funktioniert - es gefolgert, dass f
durch Int
parametrisiert werden muss, weil der Rückgabetyp ein Int
sein muss (weil f2
ist ein Int
).
Beachten Sie, dass, wenn wir implicit a: A
entfernen und nur die Reihenfolge impliziten Parameter verlassen, bleibt der Fehler, aber
Diverging implicit expansion for type Ordering[A] starting with method Tuple9 in object Ordering.
Wieder wird, geben Sie Parameter hinzufügen, so dass es val f2: Int = f[Int]()
hilft wird.
Was ist los? Warum kann der Compiler folgern, dass der Parameter A
ein Int
sein muss, aber nicht dass der Parameter Ordering[A]
ein Ordering[Int]
sein muss?
Sieht aus wie [SI-8541] (https://issues.scala-lang.org/browse/SI-8541) –