From 36feaad84e48d13e33a49ef9d6a5356ff8d7a200 Mon Sep 17 00:00:00 2001 From: Tim Spence Date: Fri, 19 Mar 2021 10:14:31 +0000 Subject: [PATCH 1/3] Representable instance for Tuple2K --- core/src/main/scala/cats/data/Tuple2K.scala | 22 +++++++++++++++++++ .../test/scala/cats/tests/Tuple2KSuite.scala | 12 ++++++++++ 2 files changed, 34 insertions(+) diff --git a/core/src/main/scala/cats/data/Tuple2K.scala b/core/src/main/scala/cats/data/Tuple2K.scala index 97a347b62d..b0fa6f8200 100644 --- a/core/src/main/scala/cats/data/Tuple2K.scala +++ b/core/src/main/scala/cats/data/Tuple2K.scala @@ -96,6 +96,28 @@ sealed abstract private[data] class Tuple2KInstances1 extends Tuple2KInstances2 def F: Foldable[F] = FF def G: Foldable[G] = GF } + + implicit def catsDataRepresentableForTuple2K[F[_], G[_]](implicit + FF: Representable[F], + GG: Representable[G] + ): Representable.Aux[Tuple2K[F, G, *], Either[FF.Representation, GG.Representation]] = + new Representable[Tuple2K[F, G, *]] { + type Representation = Either[FF.Representation, GG.Representation] + + val F = new Tuple2KFunctor[F, G] { + val F = FF.F + val G = GG.F + } + + def index[A](f: Tuple2K[F, G, A]): Representation => A = { + case Left(i) => FF.index(f.first)(i) + case Right(i) => GG.index(f.second)(i) + } + + def tabulate[A](f: Representation => A): Tuple2K[F, G, A] = + Tuple2K(FF.tabulate((x: FF.Representation) => f(Left(x))), GG.tabulate((x: GG.Representation) => f(Right(x)))) + } + } sealed abstract private[data] class Tuple2KInstances2 extends Tuple2KInstances3 { diff --git a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala index 293cb889b5..f0a13df568 100644 --- a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala +++ b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala @@ -41,6 +41,18 @@ class Tuple2KSuite extends CatsSuite { checkAll("Show[Tuple2K[Option, Option, Int]]", SerializableTests.serializable(Show[Tuple2K[Option, Option, Int]])) + { + type Pair[A] = (A, A) + + checkAll( + "Representable[Tuple2K[Pair, Function1[MiniInt, *], *]]", + RepresentableTests[Tuple2K[Pair, Function1[MiniInt, *], *], Either[Boolean, MiniInt]].representable[Int] + ) + checkAll("Representable[Tuple2K[Pair, Function1[MiniInt, *], *]]", + SerializableTests.serializable(Representable[Tuple2K[Pair, Function1[MiniInt, *], *]]) + ) + } + { implicit val monoidK: MonoidK[ListWrapper] = ListWrapper.monoidK checkAll("Tuple2K[ListWrapper, ListWrapper, *]", MonoidKTests[Tuple2K[ListWrapper, ListWrapper, *]].monoidK[Int]) From 8207ed1b964b1f4a656249bca7d4875c8e429eec Mon Sep 17 00:00:00 2001 From: Tim Spence Date: Fri, 19 Mar 2021 10:33:35 +0000 Subject: [PATCH 2/3] :heart: scala 2.12 implicit resolution --- .../test/scala/cats/tests/Tuple2KSuite.scala | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala index f0a13df568..7632193830 100644 --- a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala +++ b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala @@ -8,6 +8,7 @@ import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ import cats.laws.discipline.SemigroupalTests.Isomorphisms import cats.syntax.eq._ +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Prop._ class Tuple2KSuite extends CatsSuite { @@ -44,12 +45,31 @@ class Tuple2KSuite extends CatsSuite { { type Pair[A] = (A, A) + //Scala 2.12 implicit resolution absolutely loses its mind here + implicit val help_scala2_12: Representable.Aux[Tuple2K[Pair, Pair, *], Either[Boolean, Boolean]] = + Tuple2K.catsDataRepresentableForTuple2K[Pair, Pair] + implicit val a: Arbitrary[Int] = Arbitrary.arbInt + implicit val b: Arbitrary[Tuple2K[Pair, Pair, Int]] = + catsLawsArbitraryForTuple2K[Pair, Pair, Int] + implicit val c: Arbitrary[Either[Boolean, Boolean]] = Arbitrary.arbEither(Arbitrary.arbBool, Arbitrary.arbBool) + implicit val d: Arbitrary[(Either[Boolean, Boolean]) => Int] = + Arbitrary.arbFunction1(Arbitrary.arbInt, Cogen.cogenEither(Cogen.cogenBoolean, Cogen.cogenBoolean)) + implicit val e: Eq[Tuple2K[Pair, Pair, Int]] = Tuple2K.catsDataEqForTuple2K[Pair, Pair, Int] + implicit val f: Eq[Int] = Eq.catsKernelInstancesForInt + checkAll( - "Representable[Tuple2K[Pair, Function1[MiniInt, *], *]]", - RepresentableTests[Tuple2K[Pair, Function1[MiniInt, *], *], Either[Boolean, MiniInt]].representable[Int] + "Representable[Tuple2K[Pair, Pair, *]]", + RepresentableTests[Tuple2K[Pair, Pair, *], Either[Boolean, Boolean]].representable[Int]( + a, + b, + c, + d, + e, + f + ) ) - checkAll("Representable[Tuple2K[Pair, Function1[MiniInt, *], *]]", - SerializableTests.serializable(Representable[Tuple2K[Pair, Function1[MiniInt, *], *]]) + checkAll("Representable[Tuple2K[Pair, Pair, *]]", + SerializableTests.serializable(Representable[Tuple2K[Pair, Pair, *]]) ) } From c1baaac44acf9a5ce51b4c91d1c66368c6f0a908 Mon Sep 17 00:00:00 2001 From: Tim Spence Date: Wed, 24 Mar 2021 10:05:27 +0000 Subject: [PATCH 3/3] Remove unnecessary implicits --- .../src/test/scala/cats/tests/Tuple2KSuite.scala | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala index 7632193830..a55baab81c 100644 --- a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala +++ b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala @@ -48,14 +48,13 @@ class Tuple2KSuite extends CatsSuite { //Scala 2.12 implicit resolution absolutely loses its mind here implicit val help_scala2_12: Representable.Aux[Tuple2K[Pair, Pair, *], Either[Boolean, Boolean]] = Tuple2K.catsDataRepresentableForTuple2K[Pair, Pair] - implicit val a: Arbitrary[Int] = Arbitrary.arbInt - implicit val b: Arbitrary[Tuple2K[Pair, Pair, Int]] = - catsLawsArbitraryForTuple2K[Pair, Pair, Int] - implicit val c: Arbitrary[Either[Boolean, Boolean]] = Arbitrary.arbEither(Arbitrary.arbBool, Arbitrary.arbBool) - implicit val d: Arbitrary[(Either[Boolean, Boolean]) => Int] = - Arbitrary.arbFunction1(Arbitrary.arbInt, Cogen.cogenEither(Cogen.cogenBoolean, Cogen.cogenBoolean)) - implicit val e: Eq[Tuple2K[Pair, Pair, Int]] = Tuple2K.catsDataEqForTuple2K[Pair, Pair, Int] - implicit val f: Eq[Int] = Eq.catsKernelInstancesForInt + + val a: Arbitrary[Int] = implicitly[Arbitrary[Int]] + val b: Arbitrary[Tuple2K[Pair, Pair, Int]] = implicitly[Arbitrary[Tuple2K[Pair, Pair, Int]]] + val c: Arbitrary[Either[Boolean, Boolean]] = implicitly[Arbitrary[Either[Boolean, Boolean]]] + val d: Arbitrary[(Either[Boolean, Boolean]) => Int] = implicitly[Arbitrary[(Either[Boolean, Boolean]) => Int]] + val e: Eq[Tuple2K[Pair, Pair, Int]] = Eq[Tuple2K[Pair, Pair, Int]] + val f: Eq[Int] = Eq[Int] checkAll( "Representable[Tuple2K[Pair, Pair, *]]",