From 6efef848fde6df438fec129eb6cfa4df4d3c370c Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Mon, 3 Apr 2017 09:19:52 -0400 Subject: [PATCH 1/5] move arbitray instance of StateT to laws --- laws/src/main/scala/cats/laws/discipline/Arbitrary.scala | 7 +++++++ tests/src/test/scala/cats/tests/StateTTests.scala | 7 +------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala index 039a76fc35..da1ddd5b5a 100644 --- a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala +++ b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala @@ -157,9 +157,16 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsArbitraryForNested[F[_], G[_], A](implicit FG: Arbitrary[F[G[A]]]): Arbitrary[Nested[F, G, A]] = Arbitrary(FG.arbitrary.map(Nested(_))) + + implicit def catsLawArbitraryForState[S: Arbitrary: Cogen, A: Arbitrary]: Arbitrary[State[S, A]] = + catsLawArbitraryForStateT[Eval, S, A] } private[discipline] sealed trait ArbitraryInstances0 { + + implicit def catsLawArbitraryForStateT[F[_]: Applicative, S, A](implicit F: Arbitrary[S => F[(S, A)]]): Arbitrary[StateT[F, S, A]] = + Arbitrary(F.arbitrary.map(f => StateT(f))) + implicit def catsLawsArbitraryForWriterT[F[_], L, V](implicit F: Arbitrary[F[(L, V)]]): Arbitrary[WriterT[F, L, V]] = Arbitrary(F.arbitrary.map(WriterT(_))) diff --git a/tests/src/test/scala/cats/tests/StateTTests.scala b/tests/src/test/scala/cats/tests/StateTTests.scala index 28bb8f2403..9d78e1bd58 100644 --- a/tests/src/test/scala/cats/tests/StateTTests.scala +++ b/tests/src/test/scala/cats/tests/StateTTests.scala @@ -6,7 +6,7 @@ import cats.kernel.instances.tuple._ import cats.laws.discipline._ import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ -import org.scalacheck.{Arbitrary, Cogen} +import org.scalacheck.Arbitrary class StateTTests extends CatsSuite { import StateTTests._ @@ -294,15 +294,10 @@ object StateTTests extends StateTTestsInstances { implicit def stateEq[S:Eq:Arbitrary, A:Eq]: Eq[State[S, A]] = stateTEq[Eval, S, A] - implicit def stateArbitrary[S: Arbitrary: Cogen, A: Arbitrary]: Arbitrary[State[S, A]] = - stateTArbitrary[Eval, S, A] - val add1: State[Int, Int] = State(n => (n + 1, n)) } sealed trait StateTTestsInstances { - implicit def stateTArbitrary[F[_]: Applicative, S, A](implicit F: Arbitrary[S => F[(S, A)]]): Arbitrary[StateT[F, S, A]] = - Arbitrary(F.arbitrary.map(f => StateT(f))) implicit def stateTEq[F[_], S, A](implicit S: Arbitrary[S], FSA: Eq[F[(S, A)]], F: FlatMap[F]): Eq[StateT[F, S, A]] = Eq.by[StateT[F, S, A], S => F[(S, A)]](state => From 16c06d773073b656ad1897303debf581911c922b Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Mon, 3 Apr 2017 09:51:14 -0400 Subject: [PATCH 2/5] fix FreeTTests --- free/src/test/scala/cats/free/FreeTTests.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/free/src/test/scala/cats/free/FreeTTests.scala b/free/src/test/scala/cats/free/FreeTTests.scala index c7eff2c26f..4705fbdbe9 100644 --- a/free/src/test/scala/cats/free/FreeTTests.scala +++ b/free/src/test/scala/cats/free/FreeTTests.scala @@ -7,7 +7,7 @@ import cats.data._ import cats.laws.discipline._ import cats.tests.CatsSuite import cats.instances.option._ - +import cats.laws.discipline.arbitrary.catsLawArbitraryForState import org.scalacheck.{Arbitrary, Gen, Cogen} class FreeTTests extends CatsSuite { @@ -209,7 +209,7 @@ trait FreeTTestsInstances { implicit def intStateEq[A: Eq]: Eq[IntState[A]] = stateEq[Int, A] - implicit def intStateArb[A: Arbitrary]: Arbitrary[IntState[A]] = stateArbitrary[Int, A] + implicit def intStateArb[A: Arbitrary]: Arbitrary[IntState[A]] = catsLawArbitraryForState[Int, A] implicit def freeTOptionEq[A](implicit A: Eq[A], OM: Monad[Option]): Eq[FreeTOption[A]] = new Eq[FreeTOption[A]] { def eqv(a: FreeTOption[A], b: FreeTOption[A]) = Eq[Option[A]].eqv(a.runM(identity), b.runM(identity)) From b88b2a30e11407cd817f83b22e45b20489e70ab2 Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Tue, 4 Apr 2017 09:28:34 -0400 Subject: [PATCH 3/5] added arbitrary for Reader --- core/src/main/scala/cats/data/package.scala | 1 + laws/src/main/scala/cats/laws/discipline/Arbitrary.scala | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/cats/data/package.scala b/core/src/main/scala/cats/data/package.scala index 396f22908d..1e05960990 100644 --- a/core/src/main/scala/cats/data/package.scala +++ b/core/src/main/scala/cats/data/package.scala @@ -13,6 +13,7 @@ package object data { val ReaderT = Kleisli type Reader[A, B] = ReaderT[Id, A, B] + object Reader { def apply[A, B](f: A => B): Reader[A, B] = ReaderT[Id, A, B](f) } diff --git a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala index da1ddd5b5a..c4742dfe81 100644 --- a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala +++ b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala @@ -76,8 +76,6 @@ object arbitrary extends ArbitraryInstances0 { B.perturb(seed, _), (a, b) => A.perturb(B.perturb(seed, b), a))) - implicit def catsLawsArbitraryForKleisli[F[_], A, B](implicit F: Arbitrary[F[B]]): Arbitrary[Kleisli[F, A, B]] = - Arbitrary(F.arbitrary.map(fb => Kleisli[F, A, B](_ => fb))) implicit def catsLawsArbitraryForCokleisli[F[_], A, B](implicit B: Arbitrary[B]): Arbitrary[Cokleisli[F, A, B]] = Arbitrary(B.arbitrary.map(b => Cokleisli[F, A, B](_ => b))) @@ -160,6 +158,9 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawArbitraryForState[S: Arbitrary: Cogen, A: Arbitrary]: Arbitrary[State[S, A]] = catsLawArbitraryForStateT[Eval, S, A] + + implicit def catsLawArbitraryForReader[A: Arbitrary, B: Arbitrary]: Arbitrary[Reader[A, B]] = + catsLawsArbitraryForKleisli[Id, A, B] } private[discipline] sealed trait ArbitraryInstances0 { @@ -172,4 +173,8 @@ private[discipline] sealed trait ArbitraryInstances0 { implicit def catsLawsCogenForWriterT[F[_], L, V](implicit F: Cogen[F[(L, V)]]): Cogen[WriterT[F, L, V]] = F.contramap(_.run) + + implicit def catsLawsArbitraryForKleisli[F[_], A, B](implicit F: Arbitrary[F[B]]): Arbitrary[Kleisli[F, A, B]] = + Arbitrary(F.arbitrary.map(fb => Kleisli[F, A, B](_ => fb))) + } From baf6ec4f901df1cfaf9625b3854b182a77eee6e2 Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Mon, 17 Apr 2017 12:09:04 -0400 Subject: [PATCH 4/5] added a test for the Reader Functor so that the arbitrary instance of Reader is covered --- tests/src/test/scala/cats/tests/KleisliTests.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/src/test/scala/cats/tests/KleisliTests.scala b/tests/src/test/scala/cats/tests/KleisliTests.scala index 61768b9dee..d21b66972e 100644 --- a/tests/src/test/scala/cats/tests/KleisliTests.scala +++ b/tests/src/test/scala/cats/tests/KleisliTests.scala @@ -15,6 +15,9 @@ class KleisliTests extends CatsSuite { implicit def kleisliEq[F[_], A, B](implicit A: Arbitrary[A], FB: Eq[F[B]]): Eq[Kleisli[F, A, B]] = Eq.by[Kleisli[F, A, B], A => F[B]](_.run) + implicit def readerEq[A, B](implicit A: Arbitrary[A], FB: Eq[Id[B]]): Eq[Reader[A, B]] = + Eq.by[Reader[A, B], A => Id[B]](_.run) + implicit val eitherTEq = EitherT.catsDataEqForEitherT[Kleisli[Option, Int, ?], Unit, Int] implicit val iso = CartesianTests.Isomorphisms.invariant[Kleisli[Option, Int, ?]] @@ -81,7 +84,7 @@ class KleisliTests extends CatsSuite { checkAll("Kleisli[Option, Int, Int]", FunctorTests[Kleisli[Option, Int, ?]].functor[Int, Int, Int]) checkAll("Functor[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Functor[Kleisli[Option, Int, ?]])) } - + { implicit val catsDataMonoidForKleisli = Kleisli.catsDataMonoidForKleisli[Option, Int, String] checkAll("Kleisli[Option, Int, String]", GroupLaws[Kleisli[Option, Int, String]].monoid) @@ -106,6 +109,8 @@ class KleisliTests extends CatsSuite { checkAll("SemigroupK[λ[α => Kleisli[Option, α, α]]]", SerializableTests.serializable(catsDataSemigroupKForKleisli)) } + checkAll("Reader[Int, Int]", FunctorTests[Reader[Int, ?]].functor[Int, Int, Int]) + checkAll("Kleisli[Option, ?, Int]", ContravariantTests[Kleisli[Option, ?, Int]].contravariant[Int, Int, Int]) checkAll("Contravariant[Kleisli[Option, ?, Int]]", SerializableTests.serializable(Contravariant[Kleisli[Option, ?, Int]])) From 69a641381e388d42040b7f4ded64d51b3a0729ff Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Mon, 17 Apr 2017 13:08:03 -0400 Subject: [PATCH 5/5] minor --- tests/src/test/scala/cats/tests/KleisliTests.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/test/scala/cats/tests/KleisliTests.scala b/tests/src/test/scala/cats/tests/KleisliTests.scala index d21b66972e..9fedfb3bf0 100644 --- a/tests/src/test/scala/cats/tests/KleisliTests.scala +++ b/tests/src/test/scala/cats/tests/KleisliTests.scala @@ -16,7 +16,7 @@ class KleisliTests extends CatsSuite { Eq.by[Kleisli[F, A, B], A => F[B]](_.run) implicit def readerEq[A, B](implicit A: Arbitrary[A], FB: Eq[Id[B]]): Eq[Reader[A, B]] = - Eq.by[Reader[A, B], A => Id[B]](_.run) + kleisliEq implicit val eitherTEq = EitherT.catsDataEqForEitherT[Kleisli[Option, Int, ?], Unit, Int]