Skip to content

Commit

Permalink
Merge db83772 into dd10d51
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronlevin committed Apr 26, 2016
2 parents dd10d51 + db83772 commit cb49c71
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 35 deletions.
8 changes: 8 additions & 0 deletions core/src/main/scala/cats/data/Xor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ private[data] sealed abstract class XorInstances extends XorInstances1 {
def combine(x: A Xor B, y: A Xor B): A Xor B = x combine y
}

implicit def xorSemigroupK[L]: SemigroupK[Xor[L,?]] =
new SemigroupK[Xor[L,?]] {
def combineK[A](x: Xor[L,A], y: Xor[L,A]): Xor[L,A] = x match {
case Xor.Left(_) => y
case Xor.Right(_) => x
}
}

implicit def xorBifunctor: Bitraverse[Xor] =
new Bitraverse[Xor] {
def bitraverse[G[_], A, B, C, D](fab: Xor[A, B])(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[Xor[C, D]] =
Expand Down
34 changes: 7 additions & 27 deletions core/src/main/scala/cats/data/XorT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -215,16 +215,6 @@ private[data] abstract class XorTInstances1 extends XorTInstances2 {
}
*/

/* TODO delete this when MonadCombine instance is re-enabled */
implicit def xorTMonoidK[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonoidK[XorT[F, L, ?]] = {
implicit val F0 = F
implicit val L0 = L
new MonoidK[XorT[F, L, ?]] with XorTSemigroupK[F, L] {
implicit val F = F0; implicit val L = L0
def empty[A]: XorT[F, L, A] = XorT.left(F.pure(L.empty))(F)
}
}

implicit def xorTFoldable[F[_], L](implicit F: Foldable[F]): Foldable[XorT[F, L, ?]] =
new XorTFoldable[F, L] {
val F0: Foldable[F] = F
Expand All @@ -242,10 +232,13 @@ private[data] abstract class XorTInstances2 extends XorTInstances3 {
new XorTMonadError[F, L] { implicit val F = F0 }
}

implicit def xorTSemigroupK[F[_], L](implicit F: Monad[F], L: Semigroup[L]): SemigroupK[XorT[F, L, ?]] = {
implicit val F0 = F
implicit val L0 = L
new XorTSemigroupK[F, L] { implicit val F = F0; implicit val L = L0 }
implicit def xorTSemigroupK[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 xorTEq[F[_], L, R](implicit F: Eq[F[L Xor R]]): Eq[XorT[F, L, R]] =
Expand Down Expand Up @@ -288,19 +281,6 @@ private[data] trait XorTMonadError[F[_], L] extends MonadError[XorT[F, L, ?], L]
fla.recoverWith(pf)
}

private[data] trait XorTSemigroupK[F[_], L] extends SemigroupK[XorT[F, L, ?]] {
implicit val F: Monad[F]
implicit val L: Semigroup[L]
def combineK[A](x: XorT[F, L, A], y: XorT[F, L, A]): XorT[F, L, A] =
XorT(F.flatMap(x.value) {
case Xor.Left(l1) => F.map(y.value) {
case Xor.Left(l2) => Xor.Left(L.combine(l1, l2))
case r @ Xor.Right(_) => r
}
case r @ Xor.Right(_) => F.pure[L Xor A](r)
})
}

private[data] trait XorTMonadFilter[F[_], L] extends MonadFilter[XorT[F, L, ?]] with XorTMonadError[F, L] {
implicit val F: Monad[F]
implicit val L: Monoid[L]
Expand Down
10 changes: 2 additions & 8 deletions tests/src/test/scala/cats/tests/XorTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ class XorTTests extends CatsSuite {
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]", MonoidKTests[XorT[List, String, ?]].monoidK[Int])
checkAll("MonoidK[XorT[List, String, ?]]", SerializableTests.serializable(MonoidK[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, 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 F = ListWrapper.foldable
Expand All @@ -46,12 +46,6 @@ class XorTTests extends CatsSuite {
checkAll("Eq[XorT[ListWrapper, String, Int]]", SerializableTests.serializable(Eq[XorT[ListWrapper, String, Int]]))
}

{
implicit val L = ListWrapper.semigroup[String]
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], ?]]))
}

// make sure that the Monad and Traverse instances don't result in ambiguous
// Functor instances
Functor[XorT[List, Int, ?]]
Expand Down
4 changes: 4 additions & 0 deletions tests/src/test/scala/cats/tests/XorTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package tests
import algebra.laws.{GroupLaws, OrderLaws}
import cats.data.{NonEmptyList, Xor, XorT}
import cats.data.Xor._
import cats.laws.discipline.{SemigroupKTests}
import cats.laws.discipline.arbitrary._
import cats.laws.discipline.{BitraverseTests, TraverseTests, MonadErrorTests, SerializableTests, CartesianTests}
import org.scalacheck.Arbitrary
Expand Down Expand Up @@ -31,6 +32,9 @@ class XorTests extends CatsSuite {

checkAll("Xor[Int, String]", OrderLaws[String Xor Int].order)

checkAll("Xor[ListWrapper[String], ?]", SemigroupKTests[Xor[ListWrapper[String], ?]].semigroupK[Int])
checkAll("SemigroupK[Xor[ListWrapper[String], ?]]", SerializableTests.serializable(SemigroupK[Xor[ListWrapper[String], ?]]))

{
implicit val S = ListWrapper.partialOrder[String]
implicit val I = ListWrapper.partialOrder[Int]
Expand Down

0 comments on commit cb49c71

Please sign in to comment.