diff --git a/core/src/main/scala/cats/data/Ior.scala b/core/src/main/scala/cats/data/Ior.scala index 51d29772ae..c11078e39c 100644 --- a/core/src/main/scala/cats/data/Ior.scala +++ b/core/src/main/scala/cats/data/Ior.scala @@ -708,6 +708,20 @@ sealed abstract class Ior[+A, +B] extends Product with Serializable { (a, b) => that.fold(a2 => false, b2 => false, (a2, b2) => AA.eqv(a, a2) && BB.eqv(b, b2)) ) + final def compare[AA >: A, BB >: B](that: AA Ior BB)(implicit AA: Order[AA], BB: Order[BB]): Int = + (this, that) match { + case (Ior.Left(a1), Ior.Left(a2)) => AA.compare(a1, a2) + case (Ior.Left(_), _) => -1 + case (Ior.Right(b1), Ior.Right(b2)) => BB.compare(b1, b2) + case (Ior.Right(_), Ior.Left(_)) => 1 + case (Ior.Right(_), Ior.Both(_, _)) => -1 + case (Ior.Both(a1, b1), Ior.Both(a2, b2)) => { + val r = AA.compare(a1, a2) + if (r == 0) BB.compare(b1, b2) else r + } + case (Ior.Both(_, _), _) => 1 + } + final def show[AA >: A, BB >: B](implicit AA: Show[AA], BB: Show[BB]): String = fold( a => s"Ior.Left(${AA.show(a)})", @@ -752,9 +766,10 @@ sealed abstract private[data] class IorInstances extends IorInstances0 { } } - implicit def catsDataEqForIor[A: Eq, B: Eq]: Eq[A Ior B] = - new Eq[A Ior B] { - def eqv(x: A Ior B, y: A Ior B): Boolean = x === y + implicit def catsDataOrderForIor[A: Order, B: Order]: Order[A Ior B] = + new Order[A Ior B] { + + def compare(x: Ior[A, B], y: Ior[A, B]): Int = x.compare(y) } implicit def catsDataShowForIor[A: Show, B: Show]: Show[A Ior B] = @@ -879,6 +894,12 @@ sealed abstract private[data] class IorInstances0 { override def map[B, C](fa: A Ior B)(f: B => C): A Ior C = fa.map(f) } + + implicit def catsDataEqForIor[A: Eq, B: Eq]: Eq[A Ior B] = + new Eq[A Ior B] { + + def eqv(x: A Ior B, y: A Ior B): Boolean = x === y + } } sealed private[data] trait IorFunctions { diff --git a/tests/src/test/scala/cats/tests/IorSuite.scala b/tests/src/test/scala/cats/tests/IorSuite.scala index 35af32e1cc..ddbd573bca 100644 --- a/tests/src/test/scala/cats/tests/IorSuite.scala +++ b/tests/src/test/scala/cats/tests/IorSuite.scala @@ -3,7 +3,7 @@ package cats.tests import cats.{Bitraverse, MonadError, Semigroupal, Show, Traverse} import cats.data.{EitherT, Ior, NonEmptyChain, NonEmptyList, NonEmptySet} import cats.kernel.{Eq, Semigroup} -import cats.kernel.laws.discipline.SemigroupTests +import cats.kernel.laws.discipline.{OrderTests, SemigroupTests} import cats.laws.discipline.{ BifunctorTests, BitraverseTests, @@ -37,6 +37,8 @@ class IorSuite extends CatsSuite { checkAll("BitraverseTests Ior[*, *]", BitraverseTests[Ior].bitraverse[Option, Int, Int, Int, String, String, String]) checkAll("Bitraverse[Ior]", SerializableTests.serializable(Bitraverse[Ior])) + checkAll("Order[Ior[A: Order, B: Order]]", OrderTests[Ior[Int, Int]].order) + checkAll("Semigroup[Ior[A: Semigroup, B: Semigroup]]", SemigroupTests[Ior[List[Int], List[Int]]].semigroup) checkAll("SerializableTest Semigroup[Ior[A: Semigroup, B: Semigroup]]", SerializableTests.serializable(Semigroup[Ior[List[Int], List[Int]]])