I the following code, I have evidence of R[A]
and B
is a subtype of A
, so I would expect foo
to infer the type of A
and use the RA
evidence. However, scalac refuses to do so.
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
I tried this:
def foo[T, TT >: T](x : T)(implicit ev: R[TT]) = 0
But it still does not work.
Now, if I define:
def foo[T](x : T)(implicit ev: R[TT] forSome {type TT <: T}) = 0
inference works, but in my actual code I need to refer to TT.
Edit: now that I've moved A's evidence to the A companion object, this solution seems to not work anymore. In a realistic setting, the evidence will always be in the companion object and implicit search has to find it.
Another solution is to make my evidence contravariant but this causes a lot of trouble for me like inferring Nothing
and other problems (My actual code is more complex than this simplified example).
How can I make this work correctly?
apply
method) forB
that declares its return type asA
, so thatB(1)
has typeA
. – lmm