Ответ 1
Вкратце: ваша ошибка messaage должна быть просто ошибка: тип несоответствия найдено: Заказ [Int] требуется: Int.
Причина в том, что в Ordered[A]
сравнение выполняется с помощью A
, а не с другими порядками
def <(that: A): Boolean
Это должно быть o1 < 2
, а не o1 < o2
. (конечно, 1 < 2
тоже работает, но я ожидаю, что ваш код будет просто упрощенной версией чего-то еще)
Однако, прежде чем компилятор сообщит об этой простой ошибке, если нужно искать, может ли какая-то скрытая область видимости устранить проблему. Он может преобразовать Ordering[Int]
o2
в Int
(не может) или Ordering[Int]
o1
к тому, что имеет метод def <(Ordered[Int])
, например Ordered[Ordered[Int]]
. И бывает, что он должен остановить поиск, потому что кажется, что он может продолжаться бесконечно в виде цикла. Правило дано в spec, p. От 107 до 109 (спецификация для версии 2.9). Тем не менее, правило для остановки поиска является пессимистичным, и возможно, что он удаляет строку поиска, которая могла быть успешной, поэтому компилятор считает, что он должен сообщить об этом. Хотя на самом деле, большую часть времени, как здесь, цикл был должным образом сброшен и не существовало никакого решения. Вот что вызывает удивительное сообщение об ошибке. Я думаю, что более простую ошибку следует сообщить и, что еще важнее.
Позвольте мне дать некоторые ограниченные пояснения о том, почему может существовать цикл в неявном поиске. Может быть
implicit def f(implicit a: A): B
что означает, что если у вас есть неявный A, у вас тоже есть неявный B. Таким образом, это делает граф между типами: A обеспечивает B. Это сложнее, чем это, это на самом деле гиперграф: 'implcit def f (неявный a: A, неявный b: B): C': A и B предоставляет C.
С помощью дженериков у вас есть бесконечное количество типов и бесконечный (гипер) граф, сделанный еще более сложным путем подтипирования (если вам нужен A, любой подтип A. сделает правило подтипирования, подразумеваемое ковариацией/контравариантностью )
График может содержать цикл: для получения A вы можете просто предоставить B, чтобы получить B, вы можете просто предоставить C, чтобы получить C, вы можете просто предоставить A. Это подводит итог, если вы предоставить A, вы получите A, который бесполезен, и что строки поиска должны быть удалены. Это не проблема, в данном случае это фактический цикл, и нет риска обхода возможного решения путем его сброса.
Но это может быть более сложным, так как график бесконечен, поиск может быть бесконечным без четкого циклирования. Если у вас есть
implicit def[A](x: X[X[A]]): X[A]
то если вы ищете X[Int]
, вы можете искать X[X[Int]]
вместо этого, но затем, с тем же правилом, вы ищете X[X[X[Int]]]
и так далее. Это не совсем цикл, но компилятор не преследует эти строки и называет это расходящимся. За исключением того, что может быть неявный X[X[X...X[Int]]]]]
в неявной области где-то, что сделало бы его успешным. Вот почему компилятор сообщает, что эта линия исследования была удалена.