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

Investigate why creating a Monad[[X] => A => X] instance causes ambiguous extension method errors #2

Closed
mpilquist opened this issue May 29, 2019 · 10 comments

Comments

@mpilquist
Copy link
Member

With function1.scala uncommented, expressions like List(1, 2).void result in errors like:

scala> List(1, 2).void
1 |List(1, 2).void
  |^^^^^^^^^^
  |Found:    List[Int]
  |Required: ?{ void: ? }
  |Note that implicit extension methods cannot be applied because they are ambiguous;
  |both method Function1Monad in package leopards and object ListMonad in package leopards provide an extension method `void` on List[Int]
@mpilquist mpilquist changed the title Investigate why creating a Monad[[X] => (A => X)] instance causes ambiguous extension method errors Investigate why creating a Monad[[X] => A => X] instance causes ambiguous extension method errors May 29, 2019
@dscleaver
Copy link

Is this because of List’s apply method?

@dwijnand
Copy link

Yeah, I assume it's because List extends Seq extends PartialFunction extends Function1.

@mpilquist
Copy link
Member Author

Aha! That makes sense, though I don't know how we should go about fixing here. I had hoped the more specific implied instance would have been selected.

@dscleaver
Copy link

Contextual clues help, but only a little:

scala> import implied leopards._

scala> val x : List[Unit] = List(1,2,3).void
val x: List[Unit] = List((), (), ())

scala> val x: Int => Unit = List(1,2,3).void
1 |val x: Int => Unit = List(1,2,3).void
| ^^^^^^^^^^^
|Found: List[Int]
|Required: ?{ void: ? }
|Note that implicit extension methods cannot be applied because they are ambiguous;
|both method Monad_Function1_instance in package leopards and object Monad_List_Traverse_List_instance in package leopards provide an extension method void on List[Int]

scala> val x: (Int => Unit) = (List(1,2,3): Int => Int).void
val x: Int => Unit = leopards.function1$package$Monad_Function1_instance$$Lambda$5817/671480273@789d585f

@mpilquist mpilquist reopened this Apr 22, 2021
@mpilquist
Copy link
Member Author

With 3.0.0-RC3:

[error] 7 |    assertEquals(List(1, 2) *> List(3, 4), List(3, 4, 3, 4))
[error]   |                 ^^^^^^^^^^
[error]   |Found:    List[Int]
[error]   |Required: ?{ *> : ? }
[error]   |Note that implicit extension methods cannot be applied because they are ambiguous;
[error]   |both given instance given_Monad_Function in package leopards and object given_Monad_List_Traverse_List in package leopards provide an extension method `*>` on List[Int]

@smarter
Copy link

smarter commented Apr 22, 2021

@mpilquist There's a good chance this is the same issue as scala/scala3#12126

@smarter
Copy link

smarter commented Jul 19, 2021

scala/scala3#12126 is now fixed, but this issue remains, after uncommenting src/main/scala/leopards/instances/function1.scala and setting scalaVersion to "3.0.3-RC1-bin-20210716-cc47c56-NIGHTLY" I get:

[root@test]> test:compile
[error] -- [E007] Type Mismatch Error: /home/smarter/opt/spotted-leopards/src/test/scala/leopards/FirstExample.scala:7:21 --------------------------------------------------------------------------------------------------
[error] 7 |    assertEquals(List(1, 2) *> List(3, 4), List(3, 4, 3, 4))
[error]   |                 ^^^^^^^^^^
[error]   |                 Found:    List[Int]
[error]   |                 Required: ?{ *> : ? }
[error]   |                 Note that implicit extension methods cannot be applied because they are ambiguous;
[error]   |                 both given instance given_Monad_Function in package leopards and object given_Monad_List_Traverse_List in package leopards provide an extension method `*>` on List[Int]
[error] one error found

So a minimization would still be useful here I think.

smarter added a commit to dotty-staging/dotty that referenced this issue Sep 11, 2021
When we compare polymorphic methods for specificity, we replace their
type parameters by type variables constrained in the current
context (see isAsSpecific), but for extension methods in polymorphic
givens, the comparison was done with a constraint set that does not
include the type parameters of the givens, this lead to ambiguity errors
as experienced in
typelevel/spotted-leopards#2.

We fix this by ensuring the TyperState we use for the comparison
contains any additional constraint specific to the TyperState of either
alternative. This required generalizing TyperState#mergeConstraintWith
to handle `this` not being committable (because in that case `this` does
not need to take ownership of the type variables owned by `that`,
therefore `that` itself is allowed to be committable).
@smarter
Copy link

smarter commented Sep 11, 2021

I have a fix I think: scala/scala3#13509

@smarter
Copy link

smarter commented Sep 17, 2021

Fixed as of scalaVersion := "3.1.1-RC1-bin-20210916-dd6da26-NIGHTLY"

@mpilquist
Copy link
Member Author

Fixed by #14

olsdavis pushed a commit to olsdavis/dotty that referenced this issue Apr 4, 2022
When we compare polymorphic methods for specificity, we replace their
type parameters by type variables constrained in the current
context (see isAsSpecific), but for extension methods in polymorphic
givens, the comparison was done with a constraint set that does not
include the type parameters of the givens, this lead to ambiguity errors
as experienced in
typelevel/spotted-leopards#2.

We fix this by ensuring the TyperState we use for the comparison
contains any additional constraint specific to the TyperState of either
alternative. This required generalizing TyperState#mergeConstraintWith
to handle `this` not being committable (because in that case `this` does
not need to take ownership of the type variables owned by `that`,
therefore `that` itself is allowed to be committable).
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

4 participants