cats
cats copied to clipboard
ambiguous `contains_` syntax
Frustrating I can't make a small reproducer, but here it is in the wild. https://github.com/gemini-hlsw/explore/runs/6928906317?check_suite_focus=true#step:7:56
The problem is that: https://github.com/typelevel/cats/blob/9839b7498e81b1405d3e41c88d24ce73e316e69d/core/src/main/scala/cats/syntax/unorderedFoldable.scala#L47
conflicts with
https://github.com/typelevel/cats/blob/9839b7498e81b1405d3e41c88d24ce73e316e69d/core/src/main/scala/cats/syntax/foldable.scala#L73
This is related to https://github.com/scala/bug/issues/12578.
I thought we worked through it in https://github.com/typelevel/cats/pull/4183 since I linked it in that ticket, but seems there are still problems in some situations 🤔
Aha, here's a reproducer. The issue seems to be when using it as a lambda.
//> using scala "2.13.8"
//> using lib "org.typelevel::cats-core::2.8.0"
import cats.syntax.all._
object Test {
def main(args: Array[String]): Unit = println(List("a").map(List("a").contains_))
}
[error] ./bug.scala:7:63: type mismatch;
[error] found : List[String]
[error] required: ?{def contains_: ?}
[error] Note that implicit conversions are not applicable because they are ambiguous:
[error] both method catsSyntaxFoldOps in trait FoldableSyntax of type [F[_], A](fa: F[A])(implicit evidence$2: cats.Foldable[F]): cats.syntax.FoldableOps[F,A]
[error] and method catsSyntaxUnorderedFoldableOps in trait UnorderedFoldableSyntax of type [F[_], A](fa: F[A])(implicit evidence$1: cats.UnorderedFoldable[F]): cats.syntax.UnorderedFoldableOps[F,A]
[error] are possible conversion functions from List[String] to ?{def contains_: ?}
[error] def main(args: Array[String]): Unit = println(List("a").map(List("a").contains_))
[error] ^^^^^^^^^
[error] ./bug.scala:7:63: value contains_ is not a member of List[String]
[error] did you mean contains?
[error] def main(args: Array[String]): Unit = println(List("a").map(List("a").contains_))
[error] ^^^^^^^^^^^^^^^^^^^
Rewriting as contains_(_) fixes it.
I guess it has to be fixes in the compiler - it works in Scala 3. I didn't realise that it works when not treated as a lambda.
I didn't realise that it works when not treated as a lambda.
It does but only because we rewrote the argument list to be (_, _, _) instead of (_)(implicit _, _) precisely to try and avoid this issue.
Oh ok I see - it's a trick that changed the method signature but not binary compatibility.
Nobody else has complained, this is annoying to fix, and there's an easy workaround. I'm going to put this on the backlog.
Came across this a bunch today when I upgraded to 2.8.0 on 2.13.8. Hope to upgrade to Scala 3 soon with this project but just FYI.
Darn, just when I thought I got away with it! Thanks for letting us know.
Came across this a bunch today when I upgraded to 2.8.0 on 2.13.8. Hope to upgrade to Scala 3 soon with this project but just FYI.
Similar here. Just fyi, workaround is easy enough.
I opened https://github.com/scala/bug/issues/12666 with a minimizer of this issue. Also, I might have an idea to solve it.