From 1a6019eac4a1129be31acdb2829d63bbc9def939 Mon Sep 17 00:00:00 2001 From: Mike Curry Date: Tue, 17 Nov 2015 20:19:08 +0000 Subject: [PATCH] Additional Profunctor tests covering lmap and rmap This adds additional tests for Profunctor which utilise the laws infrastructure to exercise the lmap and rmap operations. --- .../src/main/scala/cats/laws/ProfunctorLaws.scala | 15 +++++++++++++++ .../cats/laws/discipline/ProfunctorTests.scala | 7 ++++++- .../scala/cats/laws/discipline/StrongTests.scala | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/laws/src/main/scala/cats/laws/ProfunctorLaws.scala b/laws/src/main/scala/cats/laws/ProfunctorLaws.scala index 7ac69c28fe..ff7bb6743e 100644 --- a/laws/src/main/scala/cats/laws/ProfunctorLaws.scala +++ b/laws/src/main/scala/cats/laws/ProfunctorLaws.scala @@ -17,6 +17,21 @@ trait ProfunctorLaws[F[_, _]] { f2: A2 => A1, f1: A1 => A0, g1: B0 => B1, g2: B1 => B2): IsEq[F[A2, B2]] = fab.dimap(f1)(g1).dimap(f2)(g2) <-> fab.dimap(f1 compose f2)(g2 compose g1) + + def profunctorLmapIdentity[A, B](fab: F[A, B]): IsEq[F[A, B]] = + fab.lmap(identity[A]) <-> fab + + def profunctorRmapIdentity[A, B](fab: F[A, B]): IsEq[F[A, B]] = + fab.rmap(identity[B]) <-> fab + + def profunctorLmapComposition[A2, A1, A0, B](fab: F[A0, B], + f: A2 => A1, g: A1 => A0): IsEq[F[A2, B]] = + fab.lmap(g).lmap(f) <-> fab.lmap(g compose f) + + def profunctorRmapComposition[A, B2, B1, B0](fab: F[A, B0], + f: B0 => B1, g: B1 => B2): IsEq[F[A, B2]] = + fab.rmap(f).rmap(g) <-> fab.rmap(g compose f) + } object ProfunctorLaws { diff --git a/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala b/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala index 4fde5a2172..3a5d4a5a4e 100644 --- a/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala @@ -15,13 +15,18 @@ trait ProfunctorTests[F[_, _]] extends Laws { ArbFAB: Arbitrary[F[A, B]], ArbFCD: Arbitrary[F[C, D]], EqFAB: Eq[F[A, B]], + EqFAD: Eq[F[A, D]], EqFAG: Eq[F[A, G]] ): RuleSet = new DefaultRuleSet( name = "profunctor", parent = None, "profunctor identity" -> forAll(laws.profunctorIdentity[A, B] _), - "profunctor composition" -> forAll(laws.profunctorComposition[A, B, C, D, E, G] _)) + "profunctor composition" -> forAll(laws.profunctorComposition[A, B, C, D, E, G] _), + "profunctor lmap identity" -> forAll(laws.profunctorLmapIdentity[A, B] _), + "profunctor rmap identity" -> forAll(laws.profunctorRmapIdentity[A, B] _), + "profunctor lmap composition" -> forAll(laws.profunctorLmapComposition[A, B, C, D] _), + "profunctor rmap composition" -> forAll(laws.profunctorRmapComposition[A, D, C, B] _)) } object ProfunctorTests { diff --git a/laws/src/main/scala/cats/laws/discipline/StrongTests.scala b/laws/src/main/scala/cats/laws/discipline/StrongTests.scala index 93e7ffc2a0..dc07d961e4 100644 --- a/laws/src/main/scala/cats/laws/discipline/StrongTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/StrongTests.scala @@ -15,6 +15,7 @@ trait StrongTests[F[_, _]] extends ProfunctorTests[F] { ArbFBC: Arbitrary[F[B, C]], ArbFCD: Arbitrary[F[C, D]], EqFAB: Eq[F[A, B]], + EqFAD: Eq[F[A, D]], EqFAG: Eq[F[A, G]], EqFAEDE: Eq[F[(A, E), (D, E)]], EqFEAED: Eq[F[(E, A), (E, D)]]