scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.73k stars 1.04k forks source link

Resolution of given instances for nested type constructors #15344

Open TimWSpence opened 2 years ago

TimWSpence commented 2 years ago

Compiler version

3.1.2

Minimized code

In scala-cli:

//> using scala "3.1.2"

trait Contra[F[_]]:
  extension [A] (fa: F[A])
    def contramap[B](f: B => A): F[B]

object Contra:
  given Contra[[x] =>> x => Unit] with
    extension [A] (f: A => Unit)
      def contramap[B](g: B => A): B => Unit = g.andThen(f)

trait Functor[F[_]]:
  extension [A] (fa: F[A])
    def contramap[B](f: A => B): F[B]

object Functor:
  given nested[F[_], G[_]](using F: Contra[F], G: Contra[G]): Functor[[x] =>> F[G[x]]] with
    extension [A](fga: F[G[A]])
      def map[B](f: A => B): F[G[B]] = F.contramap(fga)(ga => G.contramap(ga)(f))

val x: Functor[[x] =>> (x => Unit) => Unit] = Functor.nested[[x] =>> x => Unit, [x] =>> x => Unit]
summon[Functor[[x] =>> (x => Unit) => Unit]]

Output

[error] ./repro.sc:22:45: no implicit argument of type repro.Functor[[x] =>> (x => Unit) => Unit] was found for parameter x of method summon in object Predef
[error] summon[Functor[[x] =>> (x => Unit) => Unit]]
[error]                                             ^
Error compiling project (Scala 3.1.2, JVM)
Compilation failed

Expectation

My hope was that we should resolve the Functor instance for the nested type constructors here. From my experimentation this doesn't seem to work in scala 2 either so it possibly isn't a bug. Is this intended behaviour? (I can see that there's ambiguity at least in the case where there are more than 2 nested type constructors) If it is intended then are you able to suggest any workarounds? Thanks!

odersky commented 2 years ago

What is the precise implicit argument that should be inferred? Have you tried supplying it manually?

odersky commented 2 years ago

Closing this. Please re-open if we find the implicit argument that should be inferred/

TimWSpence commented 2 years ago

Sorry for the slow reply @odersky. The implicit argument that I was hoping should be inferred was Functor.nested[[x] =>> x => Unit, [x] =>> x => Unit]

odersky commented 2 years ago

Thanks! I believe the failure here has to do with an inability to infer polymorphic function types.

TimWSpence commented 2 years ago

Thanks @odersky! This came up in the context of trying to get a scala 3 release of Kittens out. I don't suppose you're aware of any workarounds or alternative approaches that we could try in the meantime?

joroKr21 commented 2 years ago

Related: https://github.com/scala/scala/pull/6069