假设我有一个类型类:
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[...]
如果没有可供子类的类型类,我该如何自动使用超类的类型类?
答案 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方差的详细信息: