Poniżej przedstawiono uproszczoną wersję moim prawdziwy problem:Scala bug w utajonego parametru
class Z[T]
object E extends Enumeration {
implicit val z = new Z[Value]
val X, Y = Value
}
implicit def f[T : Z] = (getter: T) => 0
implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0
def e: Option[E.Value] = null
val b: Int = e
działa, z B pośrednio przekształca się o (e) (f (E.z)). Ale z małymi zmianami następujący:
implicit def f[T : Z] = (setter: T => Unit) => 0
implicit def o[T](v: Option[T])(implicit toInt: (T => Unit) => Int) = 0
zawiedzie znalezienie odpowiedniej wartości E.z niejawny chociaż nie ma istotnej różnicy od oryginalnego kodu, podczas gdy instrukcja jednoznaczne przekształcenie O (e) (f (E.z)) nadal działa.
Wiem, że implementacja niejawnego parametru nie jest jeszcze ukończona i nadal istnieje wiele nierozwiązanych problemów. Jeśli jest to jeden z nich, chciałbym zgłosić to do współpracowników Scala. Moje pytanie brzmi: a) czy to naprawdę błąd? b) jeśli tak, to gdzie i jak mogę zgłosić błąd, aby mógł zostać naprawiony w przyszłości?
UPDATE odpowiedź
Travisa pracował jak urok! Nawiasem mówiąc, powyższy kod było obejście do mojego pierwotnego problemu:
implicit object E extends Enumeration { val X, Y = Value }
implicit object F extends Enumeration { val X, Y = Value }
implicit def f[T <: Enumeration](getter: T#Value)(implicit e: T) = 0
implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0
val b: Int = Some[E.Value](null)
W tym kodzie, sytuacja była na odwrót: to działa z wersją setter ale nie z prostszej wersji pochłaniacza. Kompilator narzeka, że mylące jest używanie E lub F jako niejawnego parametru, chociaż użycie F nie kompiluje się ani nie ma sensu. Udało mi się dostać pracy robiąc coś podobnego:
implicit def f[S <% T => T, T <: Enumeration](getter: T#Value)(implicit e: T) = 0
To działa, i chociaż jakoś mogła dostać pracy, ja nadal nie rozumiem logikę tej magii.
Interesujące. Działając z '-Xlog-implicits', wydaje się, że' T' w 'f [T: Z]' nie jest wnioskowane jako 'E.Value'. Stąd działa to: 'val b: Int = o (e) (f [E.Value])' ale to nie: 'val b: Int = o (e) (f)'. – gourlaysama