2011-02-03 9 views
38

Podczas próby znalezienia rozwiązania innego pytania ([1]) natknąłem się na rozbieżny niejawny błąd rozszerzenia. Czekam na wyjaśnienia na temat tego, co oznaczaCo to jest rozbieżny niejawny błąd rozszerzenia?

Tutaj to jest w przypadku zastosowanie:

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 
               ^

Odpowiedz

19

Jeśli uruchomić to w Scala z -Xlog-implicits argument przekazany, można uzyskać więcej informacji:

scala.this.Prefed.conforms nie jest poprawna wartość ukryte dla (t) => A do z [T], ponieważ:

typu niedopasowanie:

znaleziono: <: < [T T]

wymagane: (T) => A do Z [T]

scala.this.predef.conforms nie jest poprawna wartość ukryte dla (A do Z [T]) => A do Z [A do Z [t]] ponieważ:

typu niedopasowanie:

znaleziono: <: < [A do Z [T], porządkową [t]]

wymagane: (A do Z [T]) => Zamówione [Zamówione [T]]

math.this.Ordering.ordered nie jest prawidłową wartością niejawna do zamawiania [T], ponieważ:

argumenty typu [T], nie są zgodne z metodą zamówił w granicach parametrów typu [A <: scala.math. Zlecono [A]]

Jest to głównie spekulacja, ale wydaje się, że ma to jakiś sens. Spróbuję dalej zbadać:

Wydaje się to sugerować, że są tu rozważane trzy implikacje. Ostatecznie, podpis sorted wymaga, aby znaleźć coś typu Ordering[T]. Próbuje więc zbudować ukrytą funkcję ordering. Po pierwsze, próbuje wypełnić conv, znajdując niejawny typ (T) => Ordered[T], gdzie szuka w Predef - co wydaje się jak wyskakiwanie niewłaściwego drzewa. Następnie próbuje znaleźć domyślne dla (Ordered[T]) => Ordered[Ordered[T]] w tym samym miejscu, ponieważ by przyjmuje niejawny parametr typu Ordering[S], gdzie S jest Ordered[T] na mocy conv. Więc nie może zbudować ordering.

Następnie próbuje użyć ordering w matematyce. Zamawiam, ale to też nie pasuje. Jednak myślę, że właśnie to nadaje nieco mylące przesłanie "rozbieżne implikacje". Problem nie polega na tym, że są one rozbieżne, to, że nie ma odpowiedniego zakresu, ale jest on zdezorientowany faktem, że istnieją dwie ścieżki, które można zejść. Jeśli ktoś próbuje zdefiniować def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted bez ukrytej funkcji, to kończy się niepowodzeniem z tylko ładnym komunikatem mówiącym, że nie może znaleźć odpowiedniego niejawnego.

+1

Nie wiem, myślałem, że to oznacza, że ​​jest rekurencja. "Dwie ścieżki do zejścia w dół" to "niejednoznaczne implikacje" IIUC. – nafg