Ce qui suit est une version simplifiée de mon vrai problème:Scala: bug dans le paramètre implicite
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
Cela fonctionne, avec b converti implicitement o (e) (f (E.z)). Mais avec les petites modifications suivantes:
implicit def f[T : Z] = (setter: T => Unit) => 0
implicit def o[T](v: Option[T])(implicit toInt: (T => Unit) => Int) = 0
il ne parvient à trouver la E.z valeur implicite appropriée bien qu'il n'y ait pas de différence essentielle du code d'origine, tandis que la conversion manuelle explicite à o (e) (f (E.z)) fonctionne toujours.
Je sais que l'implémentation du paramètre implicite n'est pas encore terminée et qu'il y a encore beaucoup de problèmes non résolus. Si c'est l'un d'entre eux, j'aimerais le signaler aux contributeurs Scala. Donc ma question est, a) est-ce vraiment un bug? b) si c'est le cas, où et comment puis-je déposer un bug afin qu'il puisse être corrigé dans le futur?
MISE À JOUR
Travis réponse a fonctionné comme un charme! Soit dit en passant, le code ci-dessus était une solution à mon problème d'origine:
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)
Dans ce code, la situation était l'inverse: il fonctionne avec la version setter mais pas avec la version getter plus simple. Le compilateur se plaint qu'il est difficile d'utiliser E ou F comme paramètre implicite, bien que l'utilisation de F ne compile pas et n'a pas de sens. J'ai réussi à le faire fonctionner en faisant une chose semblable:
implicit def f[S <% T => T, T <: Enumeration](getter: T#Value)(implicit e: T) = 0
Cela fonctionne, et bien que je pouvais le faire fonctionner en quelque sorte, je ne comprends toujours pas la logique derrière cette magie.
Intéressant. En cours d'exécution avec '-Xlog-implicits', il semble que' T' dans 'f [T: Z]' ne soit pas inféré comme 'E.Value'. Donc ceci fonctionne: 'val b: Int = o (e) (f [E.Value])' mais cela ne fonctionne pas: 'val b: Int = o (e) (f)'. – gourlaysama