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 に答える