Что такое расходящаяся неявная ошибка расширения? - PullRequest
43 голосов
/ 03 февраля 2011

При попытке найти решение другого вопроса ( [1] ) я натолкнулся на отклоняющуюся ошибку неявного расширения. Я ищу объяснение того, что это значит

Вот пример использования:

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
                                                ^

1 Ответ

21 голосов
/ 03 февраля 2011

Если вы запустите это в scala с переданным аргументом -Xlog-implicits, вы получите больше информации:

scala.this.Prefed.conforms не является допустимым неявным значением для (T) => Ordered [T], потому что:

несоответствие типов:

найдено: <: <[T, T] </p>

обязательно: (T) => Упорядочено [T]

scala.this.predef.conforms не является допустимым неявным значением для (Ordered [T]) => Ordered [Ordered [T]], потому что:

несоответствие типов:

найдено: <: <[Заказано [T], Заказано [T]] </p>

обязательно: (заказано [T]) => заказано [заказано [T]]

math.this.Ordering.ordered не является допустимым неявным значением для Ordering [T], потому что:

аргументы типа [T] не соответствуют границам параметра типа упорядоченного метода [A <: scala.math.Ordered [A]] </p>

Это в основном спекуляция, но, похоже, в этом есть смысл. Я попытаюсь исследовать дальше:

Кажется, это говорит о том, что здесь рассматриваются три аспекта. В конечном счете, подпись sorted требует, чтобы он нашел что-то типа Ordering[T]. Поэтому он пытается построить вашу неявную функцию ordering. Во-первых, он пытается заполнить conv, находя неявный тип (T) => Ordered[T], где он ищет в Predef, что похоже на лай неправильного дерева. Затем он пытается найти неявное значение для (Ordered[T]) => Ordered[Ordered[T]] в том же месте, поскольку by принимает неявный параметр типа Ordering[S], где S равно Ordered[T] в силу conv. Поэтому он не может построить ordering.

Затем он пытается использовать ordering в математике. Но это также не подходит. Тем не менее, я думаю, что это то, что дает некоторое запутывающее сообщение «расходящиеся последствия». Проблема не в том, что они расходятся, а в том, что нет подходящего по объему, но его смущает тот факт, что есть два пути, по которым нужно идти. Если попытаться определить def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted без неявной упорядоченной функции, то произойдет сбой с помощью простого сообщения о том, что он не может найти подходящую неявную.

...