Che cos'è un errore di espansione implicita divergente?
Domanda
Durante il tentativo di trovare una soluzione a un'altra domanda ( [1] ) Mi sono imbattuto in un errore di espansione implicito divergente.Sto cercando una spiegazione su cosa significa
Ecco il caso d'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
^
Soluzione
Se lo si esegue in scala con l'argomento -Xlog-implicits
passato, si ottengono maggiori informazioni:
scala.this.Prefed.conforms non è un valore implicito valido per (T)=> [T] ordinato perché:
tipo mancata corrispondenza:
trovato: <: <[T, T]
richiesto: (T)=> Ordinato [T]
scala.this.predef.conforms non è un valore implicito valido per (Ordered [T])=> Ordered [Ordered [T]] perché:
tipo mancata corrispondenza:
trovato: <: <[Ordered [T], Ordered [T]]
richiesto: (Ordered [T])=> Ordered [Ordered [T]]
math.this.Ordering.ordered non è un valore implicito valido per Ordering [T] perché:
gli argomenti di tipo [T] non sono conformi ai limiti del parametro di tipo ordinato del metodo [A <: scala.math.Ordered [A]]
Questa è principalmente una speculazione, ma sembra avere un senso. Proverò a indagare ulteriormente:
Questo sembra suggerire che ci sono tre impliciti che vengono considerati qui. In definitiva, la firma di sorted
richiede di trovare qualcosa di tipo Ordering[T]
. Quindi sta cercando di costruire la tua funzione implicita ordering
. In primo luogo, sta cercando di compilare conv
trovando un implicito di tipo (T) => Ordered[T]
, dove sta cercando in Predef, che sembra abbaiare sull'albero sbagliato. Sta quindi cercando di trovare un implicito per (Ordered[T]) => Ordered[Ordered[T]]
nello stesso posto, poiché by
accetta un parametro implicito di tipo Ordering[S]
, dove S
è Ordered[T]
in virtù di conv
. Quindi non può costruire ordering
.
Quindi tenta di utilizzare ordering
in matematica.Ordering, ma anche questo non va bene. Tuttavia, penso che questo sia ciò che sta dando il messaggio un po 'confuso di "impliciti divergenti". Il problema non è che stanno divergendo, è che non ce n'è uno adatto in ambito, ma è confuso dal fatto che ci sono due strade da percorrere. Se si cerca di definire def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
senza la funzione ordinata implicita, fallisce solo con un bel messaggio che dice che non è possibile trovare un implicito adatto.