From 7e764dbd9b00328525efbbc9acea55b9ca82f875 Mon Sep 17 00:00:00 2001 From: Yilin Wei Date: Thu, 9 Jun 2016 22:27:23 +0100 Subject: [PATCH 1/6] XorTInstances + cleanup tests --- core/src/main/scala/cats/data/Xor.scala | 4 + core/src/main/scala/cats/data/XorT.scala | 63 ++++++++---- .../test/scala/cats/tests/ListWrapper.scala | 30 +++++- .../src/test/scala/cats/tests/XorTTests.scala | 96 ++++++++++++++----- 4 files changed, 147 insertions(+), 46 deletions(-) diff --git a/core/src/main/scala/cats/data/Xor.scala b/core/src/main/scala/cats/data/Xor.scala index bda34ec4a4..e6ac7cd517 100644 --- a/core/src/main/scala/cats/data/Xor.scala +++ b/core/src/main/scala/cats/data/Xor.scala @@ -179,6 +179,10 @@ sealed abstract class Xor[+A, +B] extends Product with Serializable { a => s"Xor.Left(${AA.show(a)})", b => s"Xor.Right(${BB.show(b)})" ) + + def ap[AA >: A, BB >: B, C](that: AA Xor (BB => C)): AA Xor C = flatMap( + a => that.map(f => f(a)) + ) } object Xor extends XorInstances with XorFunctions { diff --git a/core/src/main/scala/cats/data/XorT.scala b/core/src/main/scala/cats/data/XorT.scala index be129f4b6b..91b8109d8d 100644 --- a/core/src/main/scala/cats/data/XorT.scala +++ b/core/src/main/scala/cats/data/XorT.scala @@ -241,7 +241,7 @@ private[data] abstract class XorTInstances extends XorTInstances1 { val F0: Traverse[F] = F } - implicit def xortTransLift[E]: TransLift.Aux[XorT[?[_], E, ?], Functor] = + implicit def catsDataTransLiftForXorT[E]: TransLift.Aux[XorT[?[_], E, ?], Functor] = new TransLift[XorT[?[_], E, ?]] { type TC[M[_]] = Functor[M] @@ -249,6 +249,9 @@ private[data] abstract class XorTInstances extends XorTInstances1 { XorT(Functor[M].map(ma)(Xor.right)) } + implicit def catsMonoidForXorT[F[_], L, A](implicit F: Monoid[F[L Xor A]]): Monoid[XorT[F, L, A]] = + new XorTMonoid[F, L, A] { implicit val F0 = F } + } private[data] abstract class XorTInstances1 extends XorTInstances2 { @@ -258,7 +261,10 @@ private[data] abstract class XorTInstances1 extends XorTInstances2 { implicit val L0 = L new XorTMonadFilter[F, L] { implicit val F = F0; implicit val L = L0 } } - */ + */ + + implicit def catsSemigroupForXorT[F[_], L, A](implicit F: Semigroup[F[L Xor A]]): Semigroup[XorT[F, L, A]] = + new XorTSemigroup[F, L, A] { implicit val F0 = F } implicit def catsDataFoldableForXorT[F[_], L](implicit F: Foldable[F]): Foldable[XorT[F, L, ?]] = new XorTFoldable[F, L] { @@ -282,19 +288,11 @@ private[data] abstract class XorTInstances2 extends XorTInstances3 { } private[data] abstract class XorTInstances3 extends XorTInstances4 { - implicit def catsDataMonadErrorForXorT[F[_], L](implicit F: Monad[F]): MonadError[XorT[F, L, ?], L] = { - implicit val F0 = F + implicit def catsDataMonadErrorForXorT[F[_], L](implicit F0: Monad[F]): MonadError[XorT[F, L, ?], L] = new XorTMonadError[F, L] { implicit val F = F0 } - } - implicit def catsDataSemigroupKForXorT[F[_], L](implicit F: Monad[F]): SemigroupK[XorT[F, L, ?]] = - new SemigroupK[XorT[F,L,?]] { - def combineK[A](x: XorT[F,L,A], y: XorT[F, L, A]): XorT[F, L, A] = - XorT(F.flatMap(x.value) { - case l @ Xor.Left(_) => y.value - case r @ Xor.Right(_) => F.pure(r) - }) - } + implicit def catsDataSemigroupKForXorT[F[_], L](implicit F0: Monad[F]): SemigroupK[XorT[F, L, ?]] = + new XorTSemigroupK[F, L] { implicit val F = F0 } implicit def catsDataEqForXorT[F[_], L, R](implicit F: Eq[F[L Xor R]]): Eq[XorT[F, L, R]] = new XorTEq[F, L, R] { @@ -302,11 +300,42 @@ private[data] abstract class XorTInstances3 extends XorTInstances4 { } } -private[data] abstract class XorTInstances4 { - implicit def catsDataFunctorForXorT[F[_], L](implicit F: Functor[F]): Functor[XorT[F, L, ?]] = { - implicit val F0 = F +private[data] abstract class XorTInstances4 extends XorTInstances5 { + implicit def catsDataApplicativeForXorT[F[_], L](implicit F0: Applicative[F]): Applicative[XorT[F, L, ?]] = + new XorTApplicative[F, L] { implicit val F = F0 } +} + +private[data] abstract class XorTInstances5 { + implicit def catsDataFunctorForXorT[F[_], L](implicit F0: Functor[F]): Functor[XorT[F, L, ?]] = new XorTFunctor[F, L] { implicit val F = F0 } - } + +} + +private[data] trait XorTSemigroup[F[_], L, A] extends Semigroup[XorT[F, L, A]] { + implicit val F0: Semigroup[F[L Xor A]] + def combine(x: XorT[F, L ,A], y: XorT[F, L , A]): XorT[F, L , A] = + XorT(F0.combine(x.value, y.value)) +} + +private[data] trait XorTMonoid[F[_], L, A] extends Monoid[XorT[F, L, A]] with XorTSemigroup[F, L, A] { + implicit val F0: Monoid[F[L Xor A]] + def empty: XorT[F, L, A] = XorT(F0.empty) +} + +private[data] trait XorTApplicative[F[_], L] extends Applicative[XorT[F, L, ?]] with XorTFunctor[F, L] { + implicit val F: Applicative[F] + def pure[A](a: A): XorT[F, L, A] = XorT(F.pure(Xor.right(a))) + def ap[A, B](x: XorT[F, L, A => B])(y: XorT[F, L, A]): XorT[F, L, B] = + XorT(F.ap(F.map(y.value)(_.ap[L, A, B] _))(x.value)) +} + +private[data] trait XorTSemigroupK[F[_], L] extends SemigroupK[XorT[F, L, ?]] { + implicit val F: Monad[F] + def combineK[A](x: XorT[F,L,A], y: XorT[F, L, A]): XorT[F, L, A] = + XorT(F.flatMap(x.value) { + case l @ Xor.Left(_) => y.value + case r @ Xor.Right(_) => F.pure(r) + }) } private[data] trait XorTFunctor[F[_], L] extends Functor[XorT[F, L, ?]] { diff --git a/tests/src/test/scala/cats/tests/ListWrapper.scala b/tests/src/test/scala/cats/tests/ListWrapper.scala index 1536f25603..469e55d28e 100644 --- a/tests/src/test/scala/cats/tests/ListWrapper.scala +++ b/tests/src/test/scala/cats/tests/ListWrapper.scala @@ -44,14 +44,21 @@ object ListWrapper { def eqv[A : Eq]: Eq[ListWrapper[A]] = Eq[List[A]].on[ListWrapper[A]](_.list) - val foldable: Foldable[ListWrapper] = - new Foldable[ListWrapper] { - def foldLeft[A, B](fa: ListWrapper[A], b: B)(f: (B, A) => B): B = - Foldable[List].foldLeft(fa.list, b)(f) + val traverse: Traverse[ListWrapper] = { + val F = Traverse[List] + new Traverse[ListWrapper] { + def foldLeft[A, B](fa: ListWrapper[A], b: B)(f: (B, A) => B): B = + F.foldLeft(fa.list, b)(f) def foldRight[A, B](fa: ListWrapper[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = - Foldable[List].foldRight(fa.list, lb)(f) + F.foldRight(fa.list, lb)(f) + def traverse[G[_], A, B](fa: ListWrapper[A])(f: A => G[B])(implicit G0: Applicative[G]): G[ListWrapper[B]] = { + G0.map(F.traverse(fa.list)(f))(ListWrapper.apply) + } } + } + + val foldable: Foldable[ListWrapper] = traverse val functor: Functor[ListWrapper] = new Functor[ListWrapper] { @@ -85,6 +92,19 @@ object ListWrapper { } } + val monadRec: MonadRec[ListWrapper] = { + val M = MonadRec[List] + + new MonadRec[ListWrapper] { + def pure[A](x: A): ListWrapper[A] = ListWrapper(M.pure(x)) + def flatMap[A, B](fa: ListWrapper[A])(f: A => ListWrapper[B]): ListWrapper[B] = ListWrapper(M.flatMap(fa.list)(a => f(a).list)) + def tailRecM[A, B](a: A)(f: A => ListWrapper[cats.data.Xor[A,B]]): ListWrapper[B] = + ListWrapper(M.tailRecM(a)(a => f(a).list)) + } + } + + val flatMapRec: FlatMapRec[ListWrapper] = monadRec + val monad: Monad[ListWrapper] = monadCombine val applicative: Applicative[ListWrapper] = monadCombine diff --git a/tests/src/test/scala/cats/tests/XorTTests.scala b/tests/src/test/scala/cats/tests/XorTTests.scala index 80c96a6601..6851fbd929 100644 --- a/tests/src/test/scala/cats/tests/XorTTests.scala +++ b/tests/src/test/scala/cats/tests/XorTTests.scala @@ -8,52 +8,100 @@ import cats.laws.discipline.arbitrary._ import cats.kernel.laws.OrderLaws class XorTTests extends CatsSuite { - implicit val eq0 = XorT.catsDataEqForXorT[List, String, String Xor Int] - implicit val eq1 = XorT.catsDataEqForXorT[XorT[List, String, ?], String, Int](eq0) - implicit val iso = CartesianTests.Isomorphisms.invariant[XorT[List, String, ?]] - checkAll("XorT[List, String, Int]", MonadErrorTests[XorT[List, String, ?], String].monadError[Int, Int, Int]) - checkAll("MonadError[XorT[List, ?, ?]]", SerializableTests.serializable(MonadError[XorT[List, String, ?], String])) - checkAll("XorT[List, String, Int]", MonadRecTests[XorT[List, String, ?]].monadRec[Int, Int, Int]) - checkAll("MonadRec[XorT[List, String, ?]]", SerializableTests.serializable(MonadRec[XorT[List, String, ?]])) - checkAll("XorT[List, ?, ?]", BifunctorTests[XorT[List, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) - checkAll("Bifunctor[XorT[List, ?, ?]]", SerializableTests.serializable(Bifunctor[XorT[List, ?, ?]])) - checkAll("XorT[List, ?, ?]", BitraverseTests[XorT[List, ?, ?]].bitraverse[Option, Int, Int, Int, String, String, String]) - checkAll("Bitraverse[XorT[List, ?, ?]]", SerializableTests.serializable(Bitraverse[XorT[List, ?, ?]])) - checkAll("XorT[List, Int, ?]", TraverseTests[XorT[List, Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) - checkAll("Traverse[XorT[List, Int, ?]]", SerializableTests.serializable(Traverse[XorT[List, Int, ?]])) - checkAll("XorT[List, String, Int]", OrderLaws[XorT[List, String, Int]].order) - checkAll("Order[XorT[List, String, Int]]", SerializableTests.serializable(Order[XorT[List, String, Int]])) - checkAll("XorT[Option, ListWrapper[String], ?]", SemigroupKTests[XorT[Option, ListWrapper[String], ?]].semigroupK[Int]) - checkAll("SemigroupK[XorT[Option, ListWrapper[String], ?]]", SerializableTests.serializable(SemigroupK[XorT[Option, ListWrapper[String], ?]])) + implicit val iso = CartesianTests.Isomorphisms.invariant[XorT[ListWrapper, String, ?]](XorT.catsDataFunctorForXorT(ListWrapper.functor)) { - implicit val F = ListWrapper.foldable - checkAll("XorT[ListWrapper, Int, ?]", FoldableTests[XorT[ListWrapper, Int, ?]].foldable[Int, Int]) - checkAll("Foldable[XorT[ListWrapper, Int, ?]]", SerializableTests.serializable(Foldable[XorT[ListWrapper, Int, ?]])) + checkAll("XorT[Option, ListWrapper[String], ?]", SemigroupKTests[XorT[Option, ListWrapper[String], ?]].semigroupK[Int]) + checkAll("SemigroupK[XorT[Option, ListWrapper[String], ?]]", SerializableTests.serializable(SemigroupK[XorT[Option, ListWrapper[String], ?]])) + } + + { + implicit val F = ListWrapper.order[String Xor Int] + + checkAll("XorT[List, String, Int]", OrderLaws[XorT[ListWrapper, String, Int]].order) + checkAll("Order[XorT[List, String, Int]]", SerializableTests.serializable(Order[XorT[ListWrapper, String, Int]])) } { + //If a Functor for F is defined implicit val F = ListWrapper.functor + + checkAll("XorT[ListWrapper, ?, ?]", BifunctorTests[XorT[ListWrapper, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) + checkAll("Bifunctor[XorT[ListWrapper, ?, ?]]", SerializableTests.serializable(Bifunctor[XorT[ListWrapper, ?, ?]])) checkAll("XorT[ListWrapper, Int, ?]", FunctorTests[XorT[ListWrapper, Int, ?]].functor[Int, Int, Int]) checkAll("Functor[XorT[ListWrapper, Int, ?]]", SerializableTests.serializable(Functor[XorT[ListWrapper, Int, ?]])) } + { + //If a Traverse for F is defined + implicit val F = ListWrapper.traverse + + checkAll("XorT[ListWrapper, Int, ?]", TraverseTests[XorT[ListWrapper, Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[XorT[ListWrapper, Int, ?]]", SerializableTests.serializable(Traverse[XorT[ListWrapper, Int, ?]])) + checkAll("XorT[ListWrapper, ?, ?]", BitraverseTests[XorT[ListWrapper, ?, ?]].bitraverse[Option, Int, Int, Int, String, String, String]) + checkAll("Bitraverse[XorT[ListWrapper, ?, ?]]", SerializableTests.serializable(Bitraverse[XorT[ListWrapper, ?, ?]])) + + } + + { + //if a Monad is defined + implicit val F = ListWrapper.monad + implicit val eq0 = XorT.catsDataEqForXorT[ListWrapper, String, String Xor Int] + implicit val eq1 = XorT.catsDataEqForXorT[XorT[ListWrapper, String, ?], String, Int](eq0) + + Functor[XorT[ListWrapper, String, ?]] + Applicative[XorT[ListWrapper, String, ?]] + Monad[XorT[ListWrapper, String, ?]] + + checkAll("XorT[ListWrapper, String, Int]", MonadErrorTests[XorT[ListWrapper, String, ?], String].monadError[Int, Int, Int]) + checkAll("MonadError[XorT[List, ?, ?]]", SerializableTests.serializable(MonadError[XorT[ListWrapper, String, ?], String])) + } + + { + //if a MonadRec is defined + implicit val F = ListWrapper.monadRec + + Functor[XorT[ListWrapper, String, ?]] + Applicative[XorT[ListWrapper, String, ?]] + Monad[XorT[ListWrapper, String, ?]] + + checkAll("XorT[ListWrapper, String, Int]", MonadRecTests[XorT[ListWrapper, String, ?]].monadRec[Int, Int, Int]) + checkAll("MonadRec[XorT[ListWrapper, String, ?]]", SerializableTests.serializable(MonadRec[XorT[ListWrapper, String, ?]])) + } + + { + //If an applicative is defined + implicit val F = ListWrapper.applicative + + Functor[XorT[ListWrapper, String, ?]] + + checkAll("XorT[ListWrapper, String, ?]", ApplicativeTests[XorT[ListWrapper, String, ?]].applicative[Int, Int, Int]) + checkAll("Applicative[XorT[ListWrapper, String, ?]]", SerializableTests.serializable(Applicative[XorT[ListWrapper, String, ?]])) + + } + + { + //If a foldable is defined + implicit val F = ListWrapper.foldable + + checkAll("XorT[ListWrapper, Int, ?]", FoldableTests[XorT[ListWrapper, Int, ?]].foldable[Int, Int]) + checkAll("Foldable[XorT[ListWrapper, Int, ?]]", SerializableTests.serializable(Foldable[XorT[ListWrapper, Int, ?]])) + } + { implicit val F = ListWrapper.partialOrder[String Xor Int] + checkAll("XorT[ListWrapper, String, Int]", OrderLaws[XorT[ListWrapper, String, Int]].partialOrder) checkAll("PartialOrder[XorT[ListWrapper, String, Int]]", SerializableTests.serializable(PartialOrder[XorT[ListWrapper, String, Int]])) } { implicit val F = ListWrapper.eqv[String Xor Int] + checkAll("XorT[ListWrapper, String, Int]", OrderLaws[XorT[ListWrapper, String, Int]].eqv) checkAll("Eq[XorT[ListWrapper, String, Int]]", SerializableTests.serializable(Eq[XorT[ListWrapper, String, Int]])) } - // make sure that the Monad and Traverse instances don't result in ambiguous - // Functor instances - Functor[XorT[List, Int, ?]] - test("toValidated") { forAll { (xort: XorT[List, String, Int]) => xort.toValidated.map(_.toXor) should === (xort.value) From d2a0912ccfffa14d2f4da4f8fafd6b125e9de99c Mon Sep 17 00:00:00 2001 From: Yilin Wei Date: Thu, 9 Jun 2016 22:34:33 +0100 Subject: [PATCH 2/6] add monoid and semigroup tests --- .../src/test/scala/cats/tests/XorTTests.scala | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/src/test/scala/cats/tests/XorTTests.scala b/tests/src/test/scala/cats/tests/XorTTests.scala index 6851fbd929..72fac0e156 100644 --- a/tests/src/test/scala/cats/tests/XorTTests.scala +++ b/tests/src/test/scala/cats/tests/XorTTests.scala @@ -5,7 +5,7 @@ import cats.functor.Bifunctor import cats.data.{Xor, XorT} import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ -import cats.kernel.laws.OrderLaws +import cats.kernel.laws.{OrderLaws, GroupLaws} class XorTTests extends CatsSuite { implicit val iso = CartesianTests.Isomorphisms.invariant[XorT[ListWrapper, String, ?]](XorT.catsDataFunctorForXorT(ListWrapper.functor)) @@ -95,6 +95,22 @@ class XorTTests extends CatsSuite { checkAll("PartialOrder[XorT[ListWrapper, String, Int]]", SerializableTests.serializable(PartialOrder[XorT[ListWrapper, String, Int]])) } + { + implicit val F = ListWrapper.semigroup[String Xor Int] + + checkAll("XorT[ListWrapper, String, Int]", GroupLaws[XorT[ListWrapper, String, Int]].semigroup) + checkAll("Semigroup[XorT[ListWrapper, String, Int]]", SerializableTests.serializable(Semigroup[XorT[ListWrapper, String, Int]])) + } + + { + implicit val F = ListWrapper.monoid[String Xor Int] + + Semigroup[XorT[ListWrapper, String, Int]] + + checkAll("XorT[ListWrapper, String, Int]", GroupLaws[XorT[ListWrapper, String, Int]].monoid) + checkAll("Monoid[XorT[ListWrapper, String, Int]]", SerializableTests.serializable(Monoid[XorT[ListWrapper, String, Int]])) + } + { implicit val F = ListWrapper.eqv[String Xor Int] From cdefe0062a113b93818d1db853d8a737b2575ccf Mon Sep 17 00:00:00 2001 From: Yilin Wei Date: Fri, 10 Jun 2016 19:16:36 +0100 Subject: [PATCH 3/6] remove applicative instance --- core/src/main/scala/cats/data/Xor.scala | 5 +++-- core/src/main/scala/cats/data/XorT.scala | 18 +++--------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/core/src/main/scala/cats/data/Xor.scala b/core/src/main/scala/cats/data/Xor.scala index e6ac7cd517..3b18b35e8b 100644 --- a/core/src/main/scala/cats/data/Xor.scala +++ b/core/src/main/scala/cats/data/Xor.scala @@ -180,8 +180,8 @@ sealed abstract class Xor[+A, +B] extends Product with Serializable { b => s"Xor.Right(${BB.show(b)})" ) - def ap[AA >: A, BB >: B, C](that: AA Xor (BB => C)): AA Xor C = flatMap( - a => that.map(f => f(a)) + def ap[AA >: A, BB >: B, C](that: AA Xor (BB => C)): AA Xor C = that.flatMap( + f => this.map(a => f(a)) ) } @@ -244,6 +244,7 @@ private[data] sealed abstract class XorInstances extends XorInstances1 { def foldLeft[B, C](fa: A Xor B, c: C)(f: (C, B) => C): C = fa.foldLeft(c)(f) def foldRight[B, C](fa: A Xor B, lc: Eval[C])(f: (B, Eval[C]) => Eval[C]): Eval[C] = fa.foldRight(lc)(f) def flatMap[B, C](fa: A Xor B)(f: B => A Xor C): A Xor C = fa.flatMap(f) + override def ap[B, C](x: A Xor (B => C))(y: A Xor B): A Xor C = y.ap(x) def pure[B](b: B): A Xor B = Xor.right(b) @tailrec def tailRecM[B, C](b: B)(f: B => A Xor (B Xor C)): A Xor C = f(b) match { diff --git a/core/src/main/scala/cats/data/XorT.scala b/core/src/main/scala/cats/data/XorT.scala index 91b8109d8d..8241f46c46 100644 --- a/core/src/main/scala/cats/data/XorT.scala +++ b/core/src/main/scala/cats/data/XorT.scala @@ -300,15 +300,9 @@ private[data] abstract class XorTInstances3 extends XorTInstances4 { } } -private[data] abstract class XorTInstances4 extends XorTInstances5 { - implicit def catsDataApplicativeForXorT[F[_], L](implicit F0: Applicative[F]): Applicative[XorT[F, L, ?]] = - new XorTApplicative[F, L] { implicit val F = F0 } -} - -private[data] abstract class XorTInstances5 { +private[data] abstract class XorTInstances4 { implicit def catsDataFunctorForXorT[F[_], L](implicit F0: Functor[F]): Functor[XorT[F, L, ?]] = new XorTFunctor[F, L] { implicit val F = F0 } - } private[data] trait XorTSemigroup[F[_], L, A] extends Semigroup[XorT[F, L, A]] { @@ -322,13 +316,6 @@ private[data] trait XorTMonoid[F[_], L, A] extends Monoid[XorT[F, L, A]] with Xo def empty: XorT[F, L, A] = XorT(F0.empty) } -private[data] trait XorTApplicative[F[_], L] extends Applicative[XorT[F, L, ?]] with XorTFunctor[F, L] { - implicit val F: Applicative[F] - def pure[A](a: A): XorT[F, L, A] = XorT(F.pure(Xor.right(a))) - def ap[A, B](x: XorT[F, L, A => B])(y: XorT[F, L, A]): XorT[F, L, B] = - XorT(F.ap(F.map(y.value)(_.ap[L, A, B] _))(x.value)) -} - private[data] trait XorTSemigroupK[F[_], L] extends SemigroupK[XorT[F, L, ?]] { implicit val F: Monad[F] def combineK[A](x: XorT[F,L,A], y: XorT[F, L, A]): XorT[F, L, A] = @@ -345,8 +332,9 @@ private[data] trait XorTFunctor[F[_], L] extends Functor[XorT[F, L, ?]] { private[data] trait XorTMonad[F[_], L] extends Monad[XorT[F, L, ?]] with XorTFunctor[F, L] { implicit val F: Monad[F] - def pure[A](a: A): XorT[F, L, A] = XorT.pure[F, L, A](a) + def pure[A](a: A): XorT[F, L, A] = XorT(F.pure(Xor.right(a))) def flatMap[A, B](fa: XorT[F, L, A])(f: A => XorT[F, L, B]): XorT[F, L, B] = fa flatMap f + override def ap[A, B](x: XorT[F, L, A => B])(y: XorT[F, L, A]): XorT[F, L, B] = super.ap(x)(y) } private[data] trait XorTMonadError[F[_], L] extends MonadError[XorT[F, L, ?], L] with XorTMonad[F, L] { From 9516f8f1443978702f36195148e464d16aa4502b Mon Sep 17 00:00:00 2001 From: Yilin Wei Date: Fri, 10 Jun 2016 19:27:48 +0100 Subject: [PATCH 4/6] would help if I commited the test --- tests/src/test/scala/cats/tests/XorTTests.scala | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/src/test/scala/cats/tests/XorTTests.scala b/tests/src/test/scala/cats/tests/XorTTests.scala index 72fac0e156..678094946b 100644 --- a/tests/src/test/scala/cats/tests/XorTTests.scala +++ b/tests/src/test/scala/cats/tests/XorTTests.scala @@ -69,17 +69,6 @@ class XorTTests extends CatsSuite { checkAll("MonadRec[XorT[ListWrapper, String, ?]]", SerializableTests.serializable(MonadRec[XorT[ListWrapper, String, ?]])) } - { - //If an applicative is defined - implicit val F = ListWrapper.applicative - - Functor[XorT[ListWrapper, String, ?]] - - checkAll("XorT[ListWrapper, String, ?]", ApplicativeTests[XorT[ListWrapper, String, ?]].applicative[Int, Int, Int]) - checkAll("Applicative[XorT[ListWrapper, String, ?]]", SerializableTests.serializable(Applicative[XorT[ListWrapper, String, ?]])) - - } - { //If a foldable is defined implicit val F = ListWrapper.foldable From 1e1b3236f015fd6c7920cb6851cdb4443838ce33 Mon Sep 17 00:00:00 2001 From: yilinwei Date: Sat, 11 Jun 2016 14:13:23 +0100 Subject: [PATCH 5/6] Address comments. --- core/src/main/scala/cats/data/Xor.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/main/scala/cats/data/Xor.scala b/core/src/main/scala/cats/data/Xor.scala index 3b18b35e8b..fce66f538e 100644 --- a/core/src/main/scala/cats/data/Xor.scala +++ b/core/src/main/scala/cats/data/Xor.scala @@ -180,9 +180,7 @@ sealed abstract class Xor[+A, +B] extends Product with Serializable { b => s"Xor.Right(${BB.show(b)})" ) - def ap[AA >: A, BB >: B, C](that: AA Xor (BB => C)): AA Xor C = that.flatMap( - f => this.map(a => f(a)) - ) + def ap[AA >: A, BB >: B, C](that: AA Xor (BB => C)): AA Xor C = that.flatMap(this.map) } object Xor extends XorInstances with XorFunctions { From 41ad7afd3b94eef0492939379a7d5fc8ffdcaa82 Mon Sep 17 00:00:00 2001 From: yilinwei Date: Sat, 11 Jun 2016 14:32:20 +0100 Subject: [PATCH 6/6] Remove useless function --- core/src/main/scala/cats/data/XorT.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/scala/cats/data/XorT.scala b/core/src/main/scala/cats/data/XorT.scala index 8241f46c46..f0c9b31ecd 100644 --- a/core/src/main/scala/cats/data/XorT.scala +++ b/core/src/main/scala/cats/data/XorT.scala @@ -334,7 +334,6 @@ private[data] trait XorTMonad[F[_], L] extends Monad[XorT[F, L, ?]] with XorTFun implicit val F: Monad[F] def pure[A](a: A): XorT[F, L, A] = XorT(F.pure(Xor.right(a))) def flatMap[A, B](fa: XorT[F, L, A])(f: A => XorT[F, L, B]): XorT[F, L, B] = fa flatMap f - override def ap[A, B](x: XorT[F, L, A => B])(y: XorT[F, L, A]): XorT[F, L, B] = super.ap(x)(y) } private[data] trait XorTMonadError[F[_], L] extends MonadError[XorT[F, L, ?], L] with XorTMonad[F, L] {