在下面的代码中,我有证据R[A]
并且B
是 的子类型A
,所以我希望foo
推断出证据的类型A
并使用RA
证据。然而,scalac 拒绝这样做。
trait R[T]
case class A(i: Int)
object A {
implicit object RA extends R[A]
}
class B(i: Int) extends A(i)
def foo[T](x : T)(implicit ev: R[T]) = 0
println(foo(new B(1))) // infers T as B and fails to find implicit R[B]
println(foo(new B(1) : A)) // Works, but undesirable
我试过这个:
def foo[T, TT >: T](x : T)(implicit ev: R[TT]) = 0
但它仍然不起作用。
现在,如果我定义:
def foo[T](x : T)(implicit ev: R[TT] forSome {type TT <: T}) = 0
推理有效,但在我的实际代码中,我需要参考 TT。
编辑:现在我已将 A 的证据移至 A 伴生对象,此解决方案似乎不再适用。在现实环境中,证据将始终存在于伴随对象中,隐式搜索必须找到它。
另一个解决方案是让我的证据逆变,但这会给我带来很多麻烦,比如推断Nothing
和其他问题(我的实际代码比这个简化的例子更复杂)。
我怎样才能使它正常工作?