如何调试和修复发散隐式

nz_*_*_21 1 scala implicit

我是 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]();
  }
}

Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

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.

Run Code Online (Sandbox Code Playgroud)

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

我希望在正确的方向上有一两个指针:)

Tim*_*Tim 5

“发散”消息在这里有点令人困惑,真正的问题是对类型类如何工作的误解。它应该是这样的:

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]()
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,Human该类只是一种简单的数据类型。有一个单独的通过扩展implicit object来实现Human对象的排序Ordering[Human]

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


请注意,implicit object如果您想让事情更简洁,您可以将它放在类对象中:

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