问题
The following code compiles:
class X[U, T <: U]
object X {
implicit def genericX[U, T <: U]: X[U, T] = new X[U, T]
}
implicitly[X[String, String]] // compiles
When we make T
covariant (class X[U, +T <: U]
) it compile as well:
class X[U, +T <: U]
object X {
implicit def genericX[U, T <: U]: X[U, T] = new X[U, T]
}
implicitly[X[String, String]] // compiles
When we make T
contravariant (class X[U, -T <: U]
), compiler fails to materilize implicitly[X[String, String]]
. Strangely enough, it is able to materialize implicitly[X[Any, Any]]
:
class X[U, -T <: U]
object X {
implicit def genericX[U, T <: U]: X[U, T] = new X[U, T]
}
implicitly[X[Any, Any]] // compiles
implicitly[X[String, String]] // error: could not find an implicit value
I suspect that despite an explicit type annotation, type T
, being in a contravariant position, is prematurely fixed to Any
. Is this the expected behaviour?
Bonus point: contravariant T
does work if we fix U
:
class X[-T <: String]
object X {
implicit def genericX[T <: String]: X[T] = new X[T]
}
implicitly[X[String]] // compiles
UPDATE1: Update after response from Dmytro Mitin:
class X[U, -T] // same behaviour for invariant T
object X {
implicit def genericX[U, T](implicit ev: T <:< U): X[U, T] = new X[U, T]
}
implicitly[X[AnyRef, AnyRef]] // compiles
def check[T](implicit ev: X[AnyRef, T]): Unit = {}
check[String] // compiles
check // does not compile
来源:https://stackoverflow.com/questions/61890200/implicit-resolution-fails-for-a-contravariant-type-with-a-type-bound