Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PartialOrder and Eq instances for XorT #668

Merged
merged 1 commit into from
Nov 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions core/src/main/scala/cats/data/XorT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,9 @@ private[data] abstract class XorTInstances extends XorTInstances1 {
}
*/

implicit def xorTEq[F[_], L, R](implicit e: Eq[F[L Xor R]]): Eq[XorT[F, L, R]] =
// TODO Use Eq.instance on next algebra upgrade
new Eq[XorT[F, L, R]] {
def eqv(x: XorT[F, L, R], y: XorT[F, L, R]): Boolean = e.eqv(x.value, y.value)
implicit def xorTOrder[F[_], L, R](implicit F: Order[F[L Xor R]]): Order[XorT[F, L, R]] =
new XorTOrder[F, L, R] {
val F0: Order[F[L Xor R]] = F
}

implicit def xorTShow[F[_], L, R](implicit sh: Show[F[L Xor R]]): Show[XorT[F, L, R]] =
Expand Down Expand Up @@ -200,6 +199,11 @@ private[data] abstract class XorTInstances1 extends XorTInstances2 {
new XorTFoldable[F, L] {
val F0: Foldable[F] = F
}

implicit def xorTPartialOrder[F[_], L, R](implicit F: PartialOrder[F[L Xor R]]): PartialOrder[XorT[F, L, R]] =
new XorTPartialOrder[F, L, R] {
val F0: PartialOrder[F[L Xor R]] = F
}
}

private[data] abstract class XorTInstances2 extends XorTInstances3 {
Expand All @@ -213,6 +217,11 @@ private[data] abstract class XorTInstances2 extends XorTInstances3 {
implicit val L0 = L
new XorTSemigroupK[F, L] { implicit val F = F0; implicit val L = L0 }
}

implicit def xorTEq[F[_], L, R](implicit F: Eq[F[L Xor R]]): Eq[XorT[F, L, R]] =
new XorTEq[F, L, R] {
val F0: Eq[F[L Xor R]] = F
}
}

private[data] abstract class XorTInstances3 {
Expand Down Expand Up @@ -289,3 +298,22 @@ private[data] sealed trait XorTTraverse[F[_], L] extends Traverse[XorT[F, L, ?]]
override def traverse[G[_]: Applicative, A, B](fa: XorT[F, L, A])(f: A => G[B]): G[XorT[F, L, B]] =
fa traverse f
}

private[data] sealed trait XorTEq[F[_], L, A] extends Eq[XorT[F, L, A]] {
implicit def F0: Eq[F[L Xor A]]

override def eqv(x: XorT[F, L, A], y: XorT[F, L, A]): Boolean = x === y
}

private[data] sealed trait XorTPartialOrder[F[_], L, A] extends PartialOrder[XorT[F, L, A]] with XorTEq[F, L, A]{
override implicit def F0: PartialOrder[F[L Xor A]]

override def partialCompare(x: XorT[F, L, A], y: XorT[F, L, A]): Double =
x partialCompare y
}

private[data] sealed trait XorTOrder[F[_], L, A] extends Order[XorT[F, L, A]] with XorTPartialOrder[F, L, A]{
override implicit def F0: Order[F[L Xor A]]

override def compare(x: XorT[F, L, A], y: XorT[F, L, A]): Int = x compare y
}
15 changes: 15 additions & 0 deletions tests/src/test/scala/cats/tests/XorTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import cats.functor.Bifunctor
import cats.data.{Xor, XorT}
import cats.laws.discipline.{BifunctorTests, FoldableTests, FunctorTests, MonadErrorTests, MonoidKTests, SerializableTests, TraverseTests}
import cats.laws.discipline.arbitrary._
import algebra.laws.OrderLaws

class XorTTests extends CatsSuite {
implicit val eq0 = XorT.xorTEq[List, String, String Xor Int]
Expand All @@ -17,6 +18,8 @@ class XorTTests extends CatsSuite {
checkAll("Bifunctor[XorT[List, ?, ?]]", SerializableTests.serializable(Bifunctor[XorT[List, ?, ?]]))
checkAll("XorT[List, Int, ?]", TraverseTests[XorT[List, Int, ?]].foldable[Int, Int])
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]]))

{
implicit val F = ListWrapper.foldable
Expand All @@ -30,6 +33,18 @@ class XorTTests extends CatsSuite {
checkAll("Functor[XorT[ListWrapper, Int, ?]]", SerializableTests.serializable(Functor[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, ?]]
Expand Down