Skip to content

Fix #18763: Run type inference before implicit search #23020

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Alex1005a
Copy link
Contributor

Fixes #18763
It seems that the problem is that searching for an instance of Functor[F] for the implicit conversion toFunctorOps tries all possible variants, because F is not constrained in any way. After failure in the case of AmbiguousImplicits, type inference occurs (F is constrained to IO) and the required instance is found. Inferring types before searching for an instance will help to avoid such cases.

@Alex1005a
Copy link
Contributor Author

The fact that type inference only happens when an "ambiguous implicit" error occurs can lead to weird things.

import cats.effect.IO
import cats.implicits.*
import cats.effect.kernel.Async
import cats.Monad

case class SomeF[F[_], A]()

object SomeF {
  implicit def asyncForSomeF[F[_]](implicit F: Async[F]): Async[[A] =>> SomeF[F, A]] = ???

  implicit def monadForSomeF1[F[_]]: Monad[[A] =>> SomeF[F, A]] = ???

  implicit def monadForSomeF2[F[_]]: Monad[[A] =>> SomeF[F, A]] = ???

  def unit[F[_]]: SomeF[F, Unit] = SomeF()
}

val test: SomeF[IO, Unit] = toFunctorOps(SomeF.unit).as(???) // toFunctorOps can be omitted

In this code, for toFunctorOps the argument asyncForSomeF will be inferred. If you remove one of the Monad implicit, the remaining one will be inferred (for example, if you remove monadForSomeF2, then monadForSomeF1 will be inferred). If you remove both Monad implicit, then an error will be output that implicit not found.
If type inference was before implicit search, there would not be such strange behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant