Qu'est-ce qu'une erreur d'extension implicite divergente?
Question
Tout en essayant de trouver une solution à une autre question ([1]) Je suis tombé sur une erreur d'expansion implicite divergente. Je cherche une explication sur ce que cela signifie
Voici le cas d'utilisation:
scala> implicit def ordering[T](implicit conv: T => Ordered[T], res: Ordering[Ordered[T]]) = Ordering.by(conv)
ordering: [T](implicit conv: (T) => Ordered[T],implicit res: Ordering[Ordered[T]])scala.math.Ordering[T]
scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
<console>:6: error: diverging implicit expansion for type Ordering[T]
starting with method ordering in object $iw
def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
^
La solution
Si vous exécutez ceci à Scala avec le -Xlog-implicits
Argument passé, vous obtenez plus d'informations:
scala.this.prefed.conformes n'est pas une valeur implicite valide pour (t) => ordonné [t] car:
incompatibilité de type:
trouvé: <: <[t, t
requis: (t) => ordonné [t
scala.this.predef.conformes n'est pas une valeur implicite valide pour (ordonné [t]) => ordonné [ordonné [t]] car:
incompatibilité de type:
trouvé: <: <[ordonné [t], ordonné [t]
requis: (ordonné [t]) => ordonné [ordonné [t]
Math.CoS.Ordering.Dorsed n'est pas une valeur implicite valide pour la commande [t] parce que:
Les arguments de type [t] ne sont pas conformes aux limites du paramètre de type de la méthode [a <: scala.math.ordre [a]
C'est principalement de la spéculation, mais cela semble avoir un sens. J'essaierai d'enquêter davantage:
Cela semble suggérer qu'il y a trois implicits qui sont pris en compte ici. En fin de compte, la signature de sorted
nécessite qu'il trouve quelque chose de type Ordering[T]
. Il essaie donc de construire votre fonction implicite ordering
. Premièrement, il essaie de remplir conv
en trouvant un implicite de type (T) => Ordered[T]
, où il cherche dans Predef - ce qui semble aboyer le mauvais arbre. Il essaie alors de trouver un implicite pour (Ordered[T]) => Ordered[Ordered[T]]
au même endroit, puisque by
prend un paramètre implicite de type Ordering[S]
, où S
est Ordered[T]
En vertu de conv
. Donc il ne peut pas construire ordering
.
Il essaie alors d'utiliser ordering
en mathématiques, mais cela ne convient pas non plus. Cependant, je pense que c'est ce qui donne au message des «implicits divergents» quelque peu déroutants. Le problème n'est pas qu'ils divergent, c'est qu'il n'y en a pas de portée appropriée, mais il est confus par le fait qu'il y a deux chemins à emprunter. Si l'on essaie de définir def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
Sans la fonction ordonnée implicite, il échoue avec un bon message disant qu'il ne peut pas trouver un implicite approprié.