-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
fix ambiguous ContravariantShow[SortedSet[A]] (& SortedMap) #4575
Conversation
core/src/main/scala/cats/Show.scala
Outdated
implicit def catsShowForSortedSet[A: Show]: Show[SortedSet[A]] = cats.instances.sortedSet.catsStdShowForSortedSet[A] | ||
implicit def catsShowForSortedMap[K: Show, V: Show]: Show[SortedMap[K, V]] = | ||
cats.instances.sortedMap.catsStdShowForSortedMap[K, V] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like now Show
will be ambiguous. What if we move catsShowForSet
and catsShowForMap
up instead? Does it work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also adding a test would be great (well not really a test, just summon the instance in test code - I think if you look for it there are places that test summoning some instance compiles).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not seeing an error trying to summon, e.g. Show[SortedMap[Int, String]]
with this patch. Should I be looking at another test case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I did not write that anywhere, but my change was largely motivated by the observation that Duration and FiniteDuration are like that and their implicits are OK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, my bad - you're right. The rule goes like this:
class DefinesA { implicit a: A }
class DefinesB { implicit b: B }
- if
A <:< B
thena
gets a point in the implicit score - if
DefinesB
<:<DefinesA
thenb
gets a point in the implicit score - so both would be 1:1 so ambiguous
However, Show[SortedSet[A]]
is not a subtype of Show[Set[A]]
because Show
is invariant.
It just looked similar to issues we've had in the past like this one: #4569
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this makes me think that it will pick the wrong instance for SortedSet
and SortedMap
- I guess that warrants adding a unit test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also BitSet
has the same issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this makes me think that it will pick the wrong instance for
SortedSet
andSortedMap
- I guess that warrants adding a unit test.
It does seem to be the case (for implicitly[ContravariantShow[...]], since as you noted Show[...] cannot have that problem, being invariant).
I'll look into it more when I can, hopefully before Monday.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The relationship between SortedSet
and Set
is the same as List
and Seq
, e.g.
And the instance for Seq
is even further down, so the opposite - we moved Seq
, not List
Some good news: I've added tests for Some less good news but it's okay, kinda: |
@@ -120,8 +117,12 @@ object Show extends ScalaVersionSpecificShowInstances with ShowInstances { | |||
private[cats] trait ShowInstances extends cats.instances.NTupleShowInstances with ShowInstances0 { | |||
implicit def catsShowForFiniteDuration: Show[FiniteDuration] = | |||
cats.instances.finiteDuration.catsStdShowForFiniteDurationUnambiguous | |||
|
|||
implicit def catsShowForSortedSet[A: Show]: Show[SortedSet[A]] = cats.instances.sortedSet.catsStdShowForSortedSet[A] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could've stayed in the old position
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I move catsShowForSortedSet back where it was in the Show companion object, I get an ambiguous implicit error on ContravariantShow[BitSet]
[...]\cats\tests\shared\src\test\scala\cats\tests\ShowSuite.scala:92:15
ambiguous implicit values:
both method catsShowForBitSet in object Show of type cats.Show[scala.collection.immutable.BitSet]
and method catsShowForSortedSet in object Show of type [A](implicit evidence$8: cats.Show[A]): cats.Show[scala.collection.immutable.SortedSet[A]]
match expected type cats.Show.ContravariantShow[scala.collection.immutable.BitSet]
implicitly[ContravariantShow[BitSet]]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, BitSet
is a subtype of SortedSet
, good catch 👍
If you're interested in resolving the theoretical issue with |
That is exactly the first thing I tried, and it results in |
That's because it's the same lambda ( |
Not sure what "LMF" means, but then I realized that All in all, I'd say I'm done here. |
LambdaMetafactory, used to implement lambdas on the JVM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Fixes #4574 (I hope...)