расходящееся неявное разложение при упорядочении полиморфного класса - PullRequest
0 голосов
/ 25 ноября 2018

Почему я получаю исключение diverging implicit expansion компилятора для следующего кода?

trait Person extends Ordered [Person] {
    def age: Int
    def compare (that: Person) = this.age.compare(that.age)
}

class Dinner[A <: Person](val people: Seq[A]) {
    def who = people.sorted
}


<console>:16: error: diverging implicit expansion for type scala.math.Ordering[A]
starting with method $conforms in object Predef
           def who = people.sorted
                            ^

Хорошо, я могу использовать people.sorted[Person], но почему я должен A это его подкласс.

1 Ответ

0 голосов
/ 25 ноября 2018

Вы указали, как сравнивать Person с, но не для A <: Person, а в people.sorted компилятор должен знать, как это сделать.

Попробуйте

trait Person extends Ordered [Person] { 
  def age: Int
  def compare(that: Person): Int = implicitly[Ordering[Person]].compare(this, that)
}

implicit def personOrdering[A <: Person]: Ordering[A] = (x, y) => x.age.compare(y.age)

class Dinner[A <: Person](val people: Seq[A]) {
  def who: Seq[A] = people.sorted
}

case class PersonImpl(age: Int) extends Person
val dinner = new Dinner[PersonImpl](Seq(PersonImpl(30), PersonImpl(20)))
dinner.who // List(PersonImpl(20), PersonImpl(30))
...