3

假设我有一个类型类:

trait ToString[T] {
  def toString(t: T): String
}

还有以下皮条客:

implicit def ToStr[T: ToString](t: T) = new {
  def toStr: String = implicitly[ToString[T]] toString t
}

现在让我们测试一下:

class A
implicit object AToString extends ToString[A] {
  def toString(a: A) = "A"
}
(new A).toStr // A

很好,到目前为止。但是如果我引入一个子BA

class B extends A
(new B).toStr // could not find implicit value for evidence parameter of type ToString[B]

所以我尝试了:

implicit def foo[X: ToString, Y <: X]: ToString[Y] = new ToString[Y] {
  def toString(y: Y): String = implicitly[ToString[X]] toString y
}

但后来我得到:

(new B).toStr // diverging implicit expansion for type ToString[...]

如果子类没有可用的类型类,我该怎么做才能自动使用超类的类型类?

4

1 回答 1

10

您应该使“ToString”的类型参数逆变:

trait ToString[-T] {
  def toString(t: T): String
}

implicit def ToStr[T: ToString](t: T) = new {
    def toStr: String = implicitly[ToString[T]] toString t
}

class A
implicit object AToString extends ToString[A] {
    def toString(a: A) = "A"
}

(new A).toStr // A

class B extends A
(new B).toStr // A

您可以在此处找到有关 scala 方差的一些详细信息:

于 2013-03-24T17:44:51.430 回答