Skip to content

Commit

Permalink
Add Order instance for NonEmptySet (#2779) (#2787)
Browse files Browse the repository at this point in the history
* Add Order instance for NonEmptySet (#2779)

- Add Serializable tests for NonEmptySet instances

* remove old catsDataEqForNonEmptySet. Name Order instance properly

* Add CatsDataMimaException to test cats.data package private binary compatibility. Simplify NonEmptySet instances hierachy

* Fix compile error

* remove redundant tests
  • Loading branch information
jatcwang authored and kailuowang committed Jun 11, 2019
1 parent 50b88fd commit 71bbf39
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
28 changes: 24 additions & 4 deletions core/src/main/scala/cats/data/NonEmptySet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package data

import cats.instances.sortedSet._
import cats.kernel._
import cats.syntax.order._

import scala.collection.immutable._

Expand Down Expand Up @@ -358,7 +359,7 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) {
}
}

sealed abstract private[data] class NonEmptySetInstances {
sealed abstract private[data] class NonEmptySetInstances extends NonEmptySetInstances0 {
implicit val catsDataInstancesForNonEmptySet: SemigroupK[NonEmptySet] with Reducible[NonEmptySet] =
new SemigroupK[NonEmptySet] with Reducible[NonEmptySet] {

Expand Down Expand Up @@ -405,9 +406,9 @@ sealed abstract private[data] class NonEmptySetInstances {
fa.toNonEmptyList
}

implicit def catsDataEqForNonEmptySet[A: Order]: Eq[NonEmptySet[A]] =
new Eq[NonEmptySet[A]] {
def eqv(x: NonEmptySet[A], y: NonEmptySet[A]): Boolean = x === y
implicit def catsDataOrderForNonEmptySet[A](implicit A: Order[A]): Order[NonEmptySet[A]] =
new NonEmptySetOrder[A] {
implicit override def A0: Order[A] = A
}

implicit def catsDataShowForNonEmptySet[A](implicit A: Show[A]): Show[NonEmptySet[A]] =
Expand All @@ -417,3 +418,22 @@ sealed abstract private[data] class NonEmptySetInstances {
def combine(x: NonEmptySet[A], y: NonEmptySet[A]): NonEmptySet[A] = x | y
}
}

sealed abstract private[data] class NonEmptySetInstances0 {
implicit def catsDataEqForNonEmptySet[A](implicit A: Order[A]): Eq[NonEmptySet[A]] = new NonEmptySetEq[A] {
implicit override def A0: Eq[A] = A
}
}

sealed abstract private[data] class NonEmptySetOrder[A] extends Order[NonEmptySet[A]] with NonEmptySetEq[A] {
implicit override def A0: Order[A]

override def compare(x: NonEmptySet[A], y: NonEmptySet[A]): Int =
x.toSortedSet.compare(y.toSortedSet)
}

sealed private[data] trait NonEmptySetEq[A] extends Eq[NonEmptySet[A]] {
implicit def A0: Eq[A]

override def eqv(x: NonEmptySet[A], y: NonEmptySet[A]): Boolean = x === y
}
21 changes: 20 additions & 1 deletion tests/src/test/scala/cats/tests/NonEmptySetSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,36 @@ package tests
import cats.laws.discipline._
import cats.laws.discipline.arbitrary._
import cats.data.NonEmptySet
import cats.kernel.laws.discipline.{EqTests, SemilatticeTests}
import cats.kernel.Semilattice
import cats.kernel.laws.discipline.{EqTests, OrderTests, PartialOrderTests, SemilatticeTests}

import scala.collection.immutable.SortedSet

class NonEmptySetSuite extends CatsSuite {

checkAll("NonEmptySet[Int]", SemigroupKTests[NonEmptySet].semigroupK[Int])
checkAll("SemigroupK[NonEmptySet[A]]", SerializableTests.serializable(SemigroupK[NonEmptySet]))

checkAll("NonEmptySet[Int]", ReducibleTests[NonEmptySet].reducible[Option, Int, Int])
checkAll("Reducible[NonEmptySet]", SerializableTests.serializable(Reducible[NonEmptySet]))

checkAll("NonEmptySet[String]", SemilatticeTests[NonEmptySet[String]].band)
checkAll("Semilattice[NonEmptySet]", SerializableTests.serializable(Semilattice[NonEmptySet[String]]))

checkAll("NonEmptySet[String]", EqTests[NonEmptySet[String]].eqv)

{
implicit val A = ListWrapper.order[Int]
checkAll("Eq[NonEmptySet[ListWrapper[Int]]]", SerializableTests.serializable(Eq[NonEmptySet[ListWrapper[Int]]]))

checkAll("NonEmptySet[ListWrapper[Int]]", OrderTests[NonEmptySet[ListWrapper[Int]]].order)
checkAll("Order[NonEmptySet[ListWrapper[Int]]]",
SerializableTests.serializable(Order[NonEmptySet[ListWrapper[Int]]]))

Eq[NonEmptySet[ListWrapper[Int]]]
PartialOrder[NonEmptySet[ListWrapper[Int]]]
}

test("First element is always the smallest") {
forAll { (nes: NonEmptySet[Int]) =>
nes.forall { v =>
Expand Down

0 comments on commit 71bbf39

Please sign in to comment.