Open
Description
Compiler version
3.3.0, 3.3.1-RC1,2.13.11,2.12.18
Minimized code
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
implicit class Extension[F[_]: Functor, A](target: F[A]) {
def map[B](f: A => B): F[B] = implicitly[Functor[F]].map(target)(f)
}
implicit def instance[X]: Functor[Container] = new Functor[Container] {
def map[A, B](fa: Container[A])(f: A => B) = Container(f(fa.value))
}
case class Container[A](value: A)
type G[A] = Container[List[A]]
def create: G[Int] = Container(List(5))
println((create: Container[List[Int]]).map(2 :: _)) // compiles
println(create.map(2 :: _)) // fails to compile
Output
value map is not a member of G[Int].
An extension method was tried, but could not be fully constructed:
Extension[[A] =>> Container[List[A]], Int](create)(instance[X])
Expectation
The type alias G[A]
causes the type parameter F[_]
of implicit class Extension
to be inferred to [A] => Container[List[A]]
which does not exhibit the required instance of Functor.
I would expect the compiler to expand G[Int]
to Container[List[Int]]
and then infer F[_]
to Container[_]
, at least when the other candidate fails to type check. Not doing so requires annotating the expanded type to call extension methods.