键入Class和Subclassing

时间:2013-03-24 17:36:29

标签: scala typeclass

假设我有一个类型类:

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

很好,到目前为止。但是,如果我引入B的子类A

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[...]

如果没有可供子类的类型类,我该如何自动使用超类的类型类?

1 个答案:

答案 0 :(得分:8)

你应该使'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方差的详细信息: