Skip to content
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

Ambiguous implicits in some cases #11

Open
kubukoz opened this issue Dec 3, 2018 · 6 comments
Open

Ambiguous implicits in some cases #11

kubukoz opened this issue Dec 3, 2018 · 6 comments
Milestone

Comments

@kubukoz
Copy link
Contributor

kubukoz commented Dec 3, 2018

Recently, I encountered this behavior:

//given
case class AppConfig(foo: FooConfig)
case class FooConfig(value: Int)

//when
implicit val readAppConfig: ApplicativeAsk[F, AppConfig] = new DefaultApplicativeAsk[F, AppConfig] {
  override val applicative: Applicative[F] = F
  override val ask: F[AppConfig] = config.pure[F]
}

//comment this line and the last line doesn't compile
implicitly[ApplicativeAsk[F, AppConfig]]

import com.olegpy.meow.hierarchy._
ApplicativeAsk[F, FooConfig]

The error I'd get if not for the implicitly[ line:

diverging implicit expansion for type cats.mtl.ApplicativeAsk[F,FooConfig]
[error] starting with method deriveApplicativeAsk in trait Priority2
[error] ApplicativeAsk[F, FooConfig]

I don't have any cats-mtl imports (apart from the type names ApplicativeAsk/DefaultApplicativeAsk). It appears like the compile isn't able to use the correct derivation method unless there's a hint from the user (being the implicitly[] call.

I'm using Scala 2.12.7 and meow-mtl 0.2.0. Do you think it's a compiler bug or something related to meow itself?

@oleg-py
Copy link
Owner

oleg-py commented Dec 4, 2018

Wow. This is crazy. And thanks for the report, btw.
Seems to be caused by an odd interaction with ApplicativeLocal inheriting ApplicativeAsk (this is the only typeclass using inheritance instead of composition), where compiler tries both methods when asked for ApplicativeAsk only. I'll try to filter that out if I figure out how or drop the ApplicativeLocal altogether.

The implicitly call seems to cause side-effect in order of implicit resolution, which in your case does not go into the loop where it's trying to derive ask from local over and over.

I'll take a look at some unspecified date in the future, hopefully this month :)

Meanwhile, workaround I can propose right now is to cherry-pick imports:

import com.olegpy.meow.hierarchy.deriveApplicativeAsk
// or
import com.olegpy.meow.hierarchy.{deriveApplicativeLocal => _, _}

@oleg-py oleg-py added this to the 0.3.0 milestone Dec 4, 2018
@kubukoz
Copy link
Contributor Author

kubukoz commented Dec 4, 2018

Worth noting: in a similar case, I moved the hierarchy import up (to the file-global imports), and it worked. I'll use cherry-picked imports in other cases, then :) thanks!

@kubukoz
Copy link
Contributor Author

kubukoz commented Jul 22, 2019

Just hit this again, and no matter where I'd put the imports (or whether i'd use the cherry-picked ones), it didn't work :(

@oleg-py
Copy link
Owner

oleg-py commented Jul 22, 2019

@kubukoz care to provide more details?

@kubukoz
Copy link
Contributor Author

kubukoz commented Jul 22, 2019

There's not much to it... but I fear it might be a strange interaction with bm4. Let me check...

@kubukoz
Copy link
Contributor Author

kubukoz commented Jul 22, 2019

Disabled bm4 so it's not that.

What I have:

ApplicativeAsk[F, Config] in implicit scope,

then I do ApplicativeAsk[F, FooConfig] (FooConfig is the type of one of the fields in Config) and it doesn't work. I tried the trick with explicitly summoning the root ask, but it didn't help either.

The error is again implicit error or diverging implicit expansion, depending on the cherry-pickiness of imports.

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

No branches or pull requests

2 participants