diff --git a/core/src/main/scala/cats/data/IorT.scala b/core/src/main/scala/cats/data/IorT.scala index bc81737b95..5c48e67db4 100644 --- a/core/src/main/scala/cats/data/IorT.scala +++ b/core/src/main/scala/cats/data/IorT.scala @@ -119,6 +119,9 @@ final case class IorT[F[_], A, B](value: F[Ior[A, B]]) { def ===(that: IorT[F, A, B])(implicit eq: Eq[F[Ior[A, B]]]): Boolean = eq.eqv(value, that.value) + def compare(that: IorT[F, A, B])(implicit ord: Order[F[Ior[A, B]]]): Int = + ord.compare(value, that.value) + def combine(that: IorT[F, A, B])(implicit F: Apply[F], A: Semigroup[A], B: Semigroup[B]): IorT[F, A, B] = IorT(F.map2(this.value, that.value)(_.combine(_))) } @@ -502,6 +505,9 @@ abstract private[data] class IorTInstances1 extends IorTInstances2 { lazy val monad: Monad[IorT[F0, E, *]] = Monad[IorT[F0, E, *]] } + implicit def catsDataOrderForIorT[F[_], A, B](implicit F: Order[F[Ior[A, B]]]): Order[IorT[F, A, B]] = + new IorTOrder[F, A, B] { val F0: Order[F[Ior[A, B]]] = F } + } abstract private[data] class IorTInstances2 extends IorTInstances3 { @@ -535,6 +541,12 @@ sealed private[data] trait IorTEq[F[_], A, B] extends Eq[IorT[F, A, B]] { override def eqv(x: IorT[F, A, B], y: IorT[F, A, B]): Boolean = x === y } +sealed private[data] trait IorTOrder[F[_], A, B] extends Order[IorT[F, A, B]] { + implicit def F0: Order[F[Ior[A, B]]] + + override def compare(x: IorT[F, A, B], y: IorT[F, A, B]): Int = x.compare(y) +} + sealed private[data] trait IorTMonad[F[_], A] extends Monad[IorT[F, A, *]] with IorTFunctor[F, A] { implicit def A0: Semigroup[A] implicit override def F0: Monad[F] diff --git a/tests/src/test/scala/cats/tests/IorTSuite.scala b/tests/src/test/scala/cats/tests/IorTSuite.scala index 93fa511574..6863b532ce 100644 --- a/tests/src/test/scala/cats/tests/IorTSuite.scala +++ b/tests/src/test/scala/cats/tests/IorTSuite.scala @@ -2,12 +2,13 @@ package cats.tests import cats.{~>, Bifunctor, Eval, Foldable, Functor, Id, Monad, MonadError, Traverse} import cats.data.{Ior, IorT} -import cats.kernel.{Eq, Monoid, Semigroup} +import cats.kernel.{Eq, Monoid, Order, Semigroup} import cats.kernel.laws.discipline.{EqTests, MonoidTests, SemigroupTests} import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ import cats.syntax.eq._ import org.scalacheck.Prop._ +import cats.kernel.laws.discipline.OrderTests class IorTSuite extends CatsSuite { @@ -61,6 +62,15 @@ class IorTSuite extends CatsSuite { checkAll("Foldable[IorT[ListWrapper, Int, *]]", SerializableTests.serializable(Foldable[IorT[ListWrapper, Int, *]])) } + { + implicit val F: Order[ListWrapper[Ior[String, Int]]] = ListWrapper.order[Ior[String, Int]] + + checkAll("IorT[ListWrapper, String, Int]", OrderTests[IorT[ListWrapper, String, Int]].order) + checkAll("Order[IorT[ListWrapper, String, Int]]", + SerializableTests.serializable(Order[IorT[ListWrapper, String, Int]]) + ) + } + { implicit val F: Semigroup[ListWrapper[Ior[String, Int]]] = ListWrapper.semigroup[Ior[String, Int]]