Pregunta

Mientras intentaba encontrar una solución a otra pregunta ([1]) Me encontré con un error de expansión implícito divergente.Estoy buscando una explicación sobre lo que esto significa.

Este es el caso de uso:

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
                                                ^
¿Fue útil?

Solución

Si ejecuta esto en Scala con el -Xlog-implicits argumento pasado, obtienes más información:

scala.this.Prefed.conforms no es un valor implícito válido para (T) => Ordered[T] porque:

el tipo no coincide:

encontró :<:<[T,T]

requerido:(T) => Ordenado[T]

scala.this.predef.conforms no es un valor implícito válido para (Ordered[T]) => Ordered[Ordered[T]] porque:

el tipo no coincide:

encontró :<:<[Ordenado[T], Ordenado[T]]

requerido :(Ordenado[T]) => Ordenado[Ordenado[T]]

math.this.Ordering.ordered no es un valor implícito válido para Ordering[T] porque:

Los argumentos de tipo [T] no se ajustan a los límites de los parámetros de tipo del método ordenado [A <:scala.math.Ordenado[A]]

Esto es principalmente especulación, pero parece tener cierto sentido.Intentaré investigar más a fondo:

Esto parece sugerir que hay tres implicaciones que se están considerando aquí.En definitiva, la firma de sorted requiere que encuentre algo de tipo Ordering[T].Entonces está tratando de construir su función implícita. ordering.En primer lugar, está intentando completar conv al encontrar un tipo implícito (T) => Ordered[T], donde está buscando en Predef, lo que parece como ladrarle al árbol equivocado.Luego está tratando de encontrar un implícito para (Ordered[T]) => Ordered[Ordered[T]] en el mismo lugar, ya que by toma un parámetro implícito de tipo Ordering[S], dónde S es Ordered[T] en virtud de conv.Entonces no puede construir ordering.

Luego intenta usar ordering en matemáticas. Ordenar, pero esto tampoco encaja.Sin embargo, creo que esto es lo que transmite el mensaje algo confuso de "implícitos divergentes".El problema no es que estén divergiendo, es que no hay uno adecuado en su alcance, sino que hay confusión por el hecho de que hay dos caminos a seguir.Si uno intenta definir def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted sin la función ordenada implícita, falla con solo un bonito mensaje que dice que no puede encontrar una función implícita adecuada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top