Skip to content

Commit

Permalink
Merge pull request #4575 from chwthewke/cats-4574
Browse files Browse the repository at this point in the history
fix ambiguous ContravariantShow[SortedSet[A]] (& SortedMap)
  • Loading branch information
satorg authored Apr 3, 2024
2 parents a2a8031 + e1c9b2c commit da8cb9b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
7 changes: 4 additions & 3 deletions core/src/main/scala/cats/Show.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ object Show extends ScalaVersionSpecificShowInstances with ShowInstances {
implicit def catsShowForQueue[A: Show]: Show[Queue[A]] = cats.instances.queue.catsStdShowForQueue[A]
implicit def catsShowForEither[A: Show, B: Show]: Show[Either[A, B]] =
cats.instances.either.catsStdShowForEither[A, B]
implicit def catsShowForSet[A: Show]: Show[Set[A]] = cats.instances.set.catsStdShowForSet[A]
implicit def catsShowForMap[K: Show, V: Show]: Show[Map[K, V]] = cats.instances.map.catsStdShowForMap[K, V]
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]

Expand All @@ -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]
}

private[cats] trait ShowInstances0 {
implicit def catsShowForSeq[A: Show]: Show[Seq[A]] = cats.instances.seq.catsStdShowForSeq[A]
implicit def catsShowForMap[K: Show, V: Show]: Show[Map[K, V]] = cats.instances.map.catsStdShowForMap[K, V]
implicit def catsShowForSet[A: Show]: Show[Set[A]] = cats.instances.set.catsStdShowForSet[A]
}
38 changes: 34 additions & 4 deletions tests/shared/src/test/scala/cats/tests/ShowSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ package cats.tests
import cats.{Contravariant, Show}
import cats.Show.ContravariantShow
import cats.kernel.Order
import cats.syntax.show._
import cats.syntax.show.*
import cats.laws.discipline.{ContravariantTests, DeferTests, MiniInt, SerializableTests}
import cats.laws.discipline.arbitrary._
import cats.laws.discipline.eq._

import cats.laws.discipline.arbitrary.*
import cats.laws.discipline.eq.*
import java.util.concurrent.TimeUnit
import scala.collection.immutable.BitSet
import scala.collection.immutable.Seq
import scala.collection.immutable.SortedMap
import scala.collection.immutable.SortedSet
import scala.concurrent.duration.{Duration, FiniteDuration}

class ShowSuite extends CatsSuite {
Expand Down Expand Up @@ -83,6 +85,34 @@ class ShowSuite extends CatsSuite {
assertEquals(show"${goodmornings.toList}", "List(guten Tag, good morning, bonjour)")
assertEquals(show"${goodmornings.toVector}", "Vector(guten Tag, good morning, bonjour)")
}

test("show interpolation with Set subtypes isn't ambiguous") {
implicitly[ContravariantShow[Set[Int]]]
implicitly[ContravariantShow[SortedSet[Int]]]
implicitly[ContravariantShow[BitSet]]

val numbers: Set[Int] = Set(4, 2, 1, 3)
// relies on the implementation of Set for <= 4 elements, maybe replace the rhs with numbers.mkString(...)?
assertEquals(show"$numbers", "Set(4, 2, 1, 3)")

val numbersSorted: SortedSet[Int] = SortedSet(4, 2, 1, 3)
assertEquals(show"$numbersSorted", "SortedSet(1, 2, 3, 4)")

val numbersBitSet: BitSet = BitSet(4, 2, 1, 3)
assertEquals(show"$numbersBitSet", "BitSet(1, 2, 3, 4)")
}

test("show interpolation with Map subtypes isn't ambiguous") {
implicitly[ContravariantShow[Map[Int, String]]]
implicitly[ContravariantShow[SortedMap[Int, String]]]

val map: Map[Int, String] = Map(3 -> "three", 1 -> "one", 4 -> "four", 2 -> "two")
// same thing as with Set, relies on an implementation detail of Map
assertEquals(show"$map", "Map(3 -> three, 1 -> one, 4 -> four, 2 -> two)")

val mapSorted: SortedMap[Int, String] = SortedMap(3 -> "three", 1 -> "one", 4 -> "four", 2 -> "two")
assertEquals(show"$mapSorted", "SortedMap(1 -> one, 2 -> two, 3 -> three, 4 -> four)")
}
}

final class ShowSuite2 extends munit.FunSuite {
Expand Down

0 comments on commit da8cb9b

Please sign in to comment.