diff --git a/core/src/main/scala/cats/std/set.scala b/core/src/main/scala/cats/std/set.scala index 0f759ad795..1efeff8350 100644 --- a/core/src/main/scala/cats/std/set.scala +++ b/core/src/main/scala/cats/std/set.scala @@ -1,6 +1,8 @@ package cats package std +import cats.syntax.show._ + trait SetInstances extends algebra.std.SetInstances { implicit val setInstance: Foldable[Set] with MonoidK[Set] = new Foldable[Set] with MonoidK[Set] { @@ -25,4 +27,9 @@ trait SetInstances extends algebra.std.SetInstances { } implicit def setMonoid[A]: Monoid[Set[A]] = MonoidK[Set].algebra[A] + + implicit def setShow[A:Show]: Show[Set[A]] = new Show[Set[A]] { + def show(fa: Set[A]): String = + fa.toIterator.map(_.show).mkString("Set(", ", ", ")") + } } diff --git a/tests/src/test/scala/cats/tests/SetTests.scala b/tests/src/test/scala/cats/tests/SetTests.scala index fc5a29541b..571b238b0b 100644 --- a/tests/src/test/scala/cats/tests/SetTests.scala +++ b/tests/src/test/scala/cats/tests/SetTests.scala @@ -11,4 +11,21 @@ class SetTests extends CatsSuite { checkAll("Set[Int]", FoldableTests[Set].foldable[Int, Int]) checkAll("Foldable[Set]", SerializableTests.serializable(Foldable[Set])) + + test("show"){ + Set(1, 1, 2, 3).show should === ("Set(1, 2, 3)") + Set.empty[String].show should === ("Set()") + + forAll { fs: Set[String] => + fs.show should === (fs.toString) + } + } + + test("show keeps separate entries for items that map to identical strings"){ + implicit val intShow: Show[Int] = Show.show(_ => "1") + // an implementation implemented as set.map(_.show).mkString(", ") would + // only show one entry in the result instead of 3, because Set.map combines + // duplicate items in the codomain. + Set(1, 2, 3).show should === ("Set(1, 1, 1)") + } }