Oto prosty program do reprodukcji, w którym definiuję typ "przemiennej" pary, który pochodzi z niejawnej konwersji kolejności. Konwersja niejawna jest stosowana przez kompilator zgodnie z oczekiwaniami, jeśli argument funkcji f
znajduje się w istniejącej wcześniej nazwanej wartości (t
w przykładzie). Jednak jeśli spróbuję wywołać f
bezpośrednio na literalnym CommutativePair
, nie powiedzie się z błędem typu. Kompilator nie stosuje w tym przypadku niejawnej konwersji kolejności.Niejawna konwersja Scala jest stosowana w pewnych warunkach, ale nie w innych.
object repro {
import scala.language.implicitConversions
case class CommutativePair[A, B](a: A, b: B)
object CommutativePair {
// Support a kind of commutative behavior via an implicit reordering
implicit def reorderPair[B, A](pair: CommutativePair[B, A]) =
CommutativePair(pair.b, pair.a)
}
// The idea is to allow a call to 'f' with Pair[Int, String] as well,
// via implicit reorder.
def f(p: CommutativePair[String, Int]) = p.toString
val t = CommutativePair(3, "c")
// This works: the implicit reordering is applied
val r1 = f(t)
// This fails to compile: the implicit reordering is ignored by the compiler
val r2 = f(CommutativePair(3, "c"))
}
Wnioskowanie o typ wydaje się nie udać; po dodaniu [Int, String] do CommutativePair kompiluje się ponownie. –
@LodewijkBogaards, zgodził się, rozważam zgłoszenie go jako błędu kompilatora scala, ale czekam, aby zobaczyć, jakie otrzymam odpowiedzi. – eje
Powinieneś. Uruchomiłem twój kod w 2.11.7 i otrzymałem ten sam problem. Chociaż mogę sobie wyobrazić, że kompilator ma z tym problem, powinien działać. –