如何调试和修复 Diverging implicits

How to debug and fix Diverging implicits

我是 scala 的初学者,我正在努力研究不同的隐式扩展。

这是我的玩具代码:


class FooList[T](implicit ord: Ordering[T]) {

}

class Human(val score: Int) extends Ordering[Human] {


  override def compare(x: Human, y: Human): Int = {
    return x.score.compareTo(y.score);  
  }
}


object Main {

  def main(args: Array[String]): Unit = {
    val h = new Human(100)
    val lst = new FooList[Human]();
  }
}

我遇到一个错误:

diverging implicit expansion for type Ordering[Human]
starting with method comparatorToOrdering in trait LowPriorityOrderingImplicits


not enough arguments for constructor FooList: (implicit ord: Ordering[Human])FooList[Human].
Unspecified value parameter ord.

https://scastie.scala-lang.org/wkSrZ6BMQKW9ZJrsZhlITQ

我希望得到一两个正确方向的指导:)

"diverging" 消息在这里有点混乱,真正的问题是对类型 class 的工作方式的误解。它应该是这样的:

class FooList[T](implicit ord: Ordering[T]) {
}

case class Human(score: Int)

implicit object HumanOrdering extends Ordering[Human] {
  def compare(x: Human, y: Human): Int =
    x.score.compareTo(y.score)
}

object Main {
  def main(args: Array[String]): Unit = {
    val h = new Human(100)
    val lst = new FooList[Human]()
  }
}

请注意,Human class 只是一种简单的数据类型。有一个单独的 implicit object 通过扩展 Ordering[Human].

实现对 Human 对象的排序

关于类型class 的要点是行为不是原始 class 的一部分,而是通过创建适当类型的 implicit 值绑定到它。这允许您向 classes 添加多个行为,而无需修改基础 class 本身。


请注意,如果您想让内容更简洁,可以将此 implicit object 放入 class 对象中:

object Human {
  implicit object HumanOrdering extends Ordering[Human] {
    def compare(x: Human, y: Human): Int =
      x.score.compareTo(y.score)
  }
}