Implicit resolution fails for a contravariant type with a type bound

核能气质少年 提交于 2020-06-26 14:59:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!