Skip to content

Commit

Permalink
Representable instance for Tuple2K (#3832)
Browse files Browse the repository at this point in the history
* Representable instance for Tuple2K

* ❤️ scala 2.12 implicit resolution

* Remove unnecessary implicits
  • Loading branch information
TimWSpence authored Mar 29, 2021
1 parent d56a856 commit f5bdab4
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
22 changes: 22 additions & 0 deletions core/src/main/scala/cats/data/Tuple2K.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
31 changes: 31 additions & 0 deletions tests/src/test/scala/cats/tests/Tuple2KSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -41,6 +42,36 @@ class Tuple2KSuite extends CatsSuite {

checkAll("Show[Tuple2K[Option, Option, Int]]", SerializableTests.serializable(Show[Tuple2K[Option, Option, Int]]))

{
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]

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, *]]",
RepresentableTests[Tuple2K[Pair, Pair, *], Either[Boolean, Boolean]].representable[Int](
a,
b,
c,
d,
e,
f
)
)
checkAll("Representable[Tuple2K[Pair, Pair, *]]",
SerializableTests.serializable(Representable[Tuple2K[Pair, Pair, *]])
)
}

{
implicit val monoidK: MonoidK[ListWrapper] = ListWrapper.monoidK
checkAll("Tuple2K[ListWrapper, ListWrapper, *]", MonoidKTests[Tuple2K[ListWrapper, ListWrapper, *]].monoidK[Int])
Expand Down

0 comments on commit f5bdab4

Please sign in to comment.