Pergunta

Ao tentar encontrar uma solução para outra questão ( [1] ) Encontrei um erro de expansão implícita divergente.Estou procurando uma explicação sobre o que isso significa

Este é o 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
                                                ^
Foi útil?

Solução

Se você executar isso em scala com o argumento -Xlog-implicits passado, você obterá mais informações:

scala.this.Prefed.conforms não é um valor implícito válido para (T)=> Ordenado [T] porque:

incompatibilidade de tipo:

encontrado: <: <[T, T]

obrigatório: (T)=> Pedido [T]

scala.this.predef.conforms não é um valor implícito válido para (Ordered [T])=> Ordered [Ordered [T]] porque:

incompatibilidade de tipo:

encontrado: <: <[Ordenado [T], Ordenado [T]]

obrigatório: (Pedido [T])=> Pedido [Pedido [T]]

math.this.Ordering.ordered não é um valor implícito válido para Ordering [T] porque:

os argumentos de tipo [T] não estão em conformidade com os limites dos parâmetros de tipo do método encomendado [A <: scala.math.Ordered [A]]

Isso é principalmente especulação, mas parece fazer algum sentido. Vou tentar investigar mais a fundo:

Isso parece sugerir que há três implícitos que estão sendo considerados aqui. Em última análise, a assinatura de sorted exige que ele encontre algo do tipo Ordering[T]. Portanto, ele está tentando construir sua função ordering implícita. Em primeiro lugar, ele está tentando preencher conv encontrando um código implícito do tipo (T) => Ordered[T], onde está pesquisando em Predef - o que parece estar latindo na árvore errada. Em seguida, ele está tentando encontrar um código implícito para (Ordered[T]) => Ordered[Ordered[T]] no mesmo lugar, já que by usa um parâmetro implícito do tipo Ordering[S], onde S é Ordered[T] em virtude de conv. Portanto, ele não pode construir ordering.

Em seguida, ele tenta usar ordering em math.Ordering, mas também não serve. No entanto, acho que é isso que está dando a mensagem um tanto confusa de 'implícitos divergentes'. O problema não é que estejam divergindo, é que não há um adequado no escopo, mas está sendo confundido pelo fato de que há dois caminhos a percorrer. Se alguém tentar definir def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted sem a função ordenada implícita, ele falhará apenas com uma boa mensagem dizendo que não foi possível encontrar um implícito adequado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top