Skip to content

Commit

Permalink
Remove AnyVal and rename to toSortedSet
Browse files Browse the repository at this point in the history
  • Loading branch information
Luka Jacobowitz committed Jan 8, 2018
1 parent 8104b40 commit 34aa71d
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 31 deletions.
28 changes: 16 additions & 12 deletions core/src/main/scala/cats/data/NonEmptySet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ import cats.{Always, Eq, Eval, Foldable, Later, Now, Reducible, SemigroupK, Show

import scala.collection.immutable._

final class NonEmptySet[A] private (val set: SortedSet[A]) extends AnyVal {
final class NonEmptySet[A] private (val set: SortedSet[A]) {

private implicit def ordering: Ordering[A] = set.ordering
private implicit def order: Order[A] = Order.fromOrdering

def +(a: A): NonEmptySet[A] = new NonEmptySet(set + a)
def ++(as: NonEmptySet[A]): NonEmptySet[A] = concat(as)
def ++(as: NonEmptySet[A]): NonEmptySet[A] = union(as)
def | (as: NonEmptySet[A]): NonEmptySet[A] = union(as)
def --(as: NonEmptySet[A]): SortedSet[A] = diff(as)
def &~(as: NonEmptySet[A]): SortedSet[A] = diff(as)
def &(as: NonEmptySet[A]): SortedSet[A] = intersect(as)

def concat(as: NonEmptySet[A]): NonEmptySet[A] = new NonEmptySet(set ++ as.set)

def -(a: A): SortedSet[A] = set - a
def map[B: Order](f: A B): NonEmptySet[B] =
Expand All @@ -46,8 +49,9 @@ final class NonEmptySet[A] private (val set: SortedSet[A]) extends AnyVal {
def apply(a: A): Boolean = set(a)
def contains(a: A): Boolean = set.contains(a)


def union(as: NonEmptySet[A]): NonEmptySet[A] = new NonEmptySet(set.union(as.toSet))
def diff(as: NonEmptySet[A]): SortedSet[A] = set -- as.set
def union(as: NonEmptySet[A]): NonEmptySet[A] = new NonEmptySet(set ++ as.set)
def intersect(as: NonEmptySet[A]): SortedSet[A] = set.filter(as.apply)
def size: Int = set.size
def forall(p: A Boolean): Boolean = set.forall(p)
def exists(f: A Boolean): Boolean = set.exists(f)
Expand Down Expand Up @@ -99,7 +103,7 @@ final class NonEmptySet[A] private (val set: SortedSet[A]) extends AnyVal {
def reduce[AA >: A](implicit S: Semigroup[AA]): AA =
S.combineAllOption(set).get

def toSet: SortedSet[A] = set
def toSortedSet: SortedSet[A] = set

/**
* Typesafe stringification method.
Expand All @@ -120,7 +124,7 @@ final class NonEmptySet[A] private (val set: SortedSet[A]) extends AnyVal {
* universal equality provided by .equals.
*/
def ===(that: NonEmptySet[A]): Boolean =
Eq[SortedSet[A]].eqv(set, that.toSet)
Eq[SortedSet[A]].eqv(set, that.toSortedSet)

def length: Int = size

Expand All @@ -139,7 +143,7 @@ final class NonEmptySet[A] private (val set: SortedSet[A]) extends AnyVal {
* }}}
*/
def zipWith[B, C: Order](b: NonEmptySet[B])(f: (A, B) => C): NonEmptySet[C] =
new NonEmptySet(SortedSet((set, b.toSet).zipped.map(f).to: _*)(Order[C].toOrdering))
new NonEmptySet(SortedSet((set, b.toSortedSet).zipped.map(f).to: _*)(Order[C].toOrdering))

def zipWithIndex: NonEmptySet[(A, Int)] =
new NonEmptySet(set.zipWithIndex)
Expand All @@ -150,7 +154,7 @@ private[data] sealed abstract class NonEmptySetInstances {
new SemigroupK[NonEmptySet] with Reducible[NonEmptySet] {

def combineK[A](a: NonEmptySet[A], b: NonEmptySet[A]): NonEmptySet[A] =
a ++ b
a | b

override def size[A](fa: NonEmptySet[A]): Long = fa.length.toLong

Expand All @@ -172,7 +176,7 @@ private[data] sealed abstract class NonEmptySetInstances {
fa.foldRight(lb)(f)

override def foldMap[A, B](fa: NonEmptySet[A])(f: A => B)(implicit B: Monoid[B]): B =
B.combineAll(fa.toSet.iterator.map(f))
B.combineAll(fa.toSortedSet.iterator.map(f))

override def fold[A](fa: NonEmptySet[A])(implicit A: Monoid[A]): A =
fa.reduce
Expand All @@ -186,7 +190,7 @@ private[data] sealed abstract class NonEmptySetInstances {
override def exists[A](fa: NonEmptySet[A])(p: A => Boolean): Boolean =
fa.exists(p)

override def toList[A](fa: NonEmptySet[A]): List[A] = fa.toSet.toList
override def toList[A](fa: NonEmptySet[A]): List[A] = fa.toSortedSet.toList

override def toNonEmptyList[A](fa: NonEmptySet[A]): NonEmptyList[A] =
NonEmptyList(fa.head, fa.tail.toList)
Expand All @@ -201,7 +205,7 @@ private[data] sealed abstract class NonEmptySetInstances {
Show.show[NonEmptySet[A]](_.show)

implicit def catsDataSemilatticeForNonEmptySet[A]: Semilattice[NonEmptySet[A]] = new Semilattice[NonEmptySet[A]] {
def combine(x: NonEmptySet[A], y: NonEmptySet[A]): NonEmptySet[A] = x ++ y
def combine(x: NonEmptySet[A], y: NonEmptySet[A]): NonEmptySet[A] = x | y
}
}

Expand Down
2 changes: 1 addition & 1 deletion laws/src/main/scala/cats/laws/discipline/Arbitrary.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ object arbitrary extends ArbitraryInstances0 {
A.arbitrary.map(a => NonEmptySet(a, fa))))

implicit def catsLawsCogenForNonEmptySet[A: Order: Cogen]: Cogen[NonEmptySet[A]] =
Cogen[SortedSet[A]].contramap(_.toSet)
Cogen[SortedSet[A]].contramap(_.toSortedSet)

implicit def catsLawsArbitraryForZipVector[A](implicit A: Arbitrary[A]): Arbitrary[ZipVector[A]] =
Arbitrary(implicitly[Arbitrary[Vector[A]]].arbitrary.map(v => new ZipVector(v)))
Expand Down
36 changes: 18 additions & 18 deletions tests/src/test/scala/cats/tests/NonEmptySetSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,56 +56,56 @@ class NonEmptySetSuite extends CatsSuite {
forAll { (i: Int, tail: SortedSet[Int]) =>
val set = tail + i
val nonEmptySet = NonEmptySet(i, tail)
set should === (nonEmptySet.toSet)
set should === (nonEmptySet.toSortedSet)
}
}

test("NonEmptySet#filter is consistent with Set#filter") {
forAll { (nes: NonEmptySet[Int], p: Int => Boolean) =>
val set = nes.toSet
val set = nes.toSortedSet
nes.filter(p) should === (set.filter(p))
}
}

test("NonEmptySet#filterNot is consistent with Set#filterNot") {
forAll { (nes: NonEmptySet[Int], p: Int => Boolean) =>
val set = nes.toSet
val set = nes.toSortedSet
nes.filterNot(p) should === (set.filterNot(p))
}
}

test("NonEmptySet#collect is consistent with Set#collect") {
forAll { (nes: NonEmptySet[Int], pf: PartialFunction[Int, String]) =>
val set = nes.toSet
val set = nes.toSortedSet
nes.collect(pf) should === (set.collect(pf))
}
}

test("NonEmptySet#find is consistent with Set#find") {
forAll { (nes: NonEmptySet[Int], p: Int => Boolean) =>
val set = nes.toSet
val set = nes.toSortedSet
nes.find(p) should === (set.find(p))
}
}

test("NonEmptySet#exists is consistent with Set#exists") {
forAll { (nes: NonEmptySet[Int], p: Int => Boolean) =>
val set = nes.toSet
val set = nes.toSortedSet
nes.exists(p) should === (set.exists(p))
}
}

test("NonEmptySet#forall is consistent with Set#forall") {
forAll { (nes: NonEmptySet[Int], p: Int => Boolean) =>
val set = nes.toSet
val set = nes.toSortedSet
nes.forall(p) should === (set.forall(p))
}
}

test("NonEmptySet#map is consistent with Set#map") {
forAll { (nes: NonEmptySet[Int], p: Int => String) =>
val set = nes.toSet
nes.map(p).toSet should === (set.map(p))
val set = nes.toSortedSet
nes.map(p).toSortedSet should === (set.map(p))
}
}

Expand Down Expand Up @@ -177,17 +177,17 @@ class NonEmptySetSuite extends CatsSuite {

test("fromSet round trip") {
forAll { l: SortedSet[Int] =>
NonEmptySet.fromSet(l).map(_.toSet).getOrElse(SortedSet.empty[Int]) should === (l)
NonEmptySet.fromSet(l).map(_.toSortedSet).getOrElse(SortedSet.empty[Int]) should === (l)
}

forAll { nes: NonEmptySet[Int] =>
NonEmptySet.fromSet(nes.toSet) should === (Some(nes))
NonEmptySet.fromSet(nes.toSortedSet) should === (Some(nes))
}
}

test("fromSetUnsafe/fromSet consistency") {
forAll { nes: NonEmptySet[Int] =>
NonEmptySet.fromSet(nes.toSet) should === (Some(NonEmptySet.fromSetUnsafe(nes.toSet)))
NonEmptySet.fromSet(nes.toSortedSet) should === (Some(NonEmptySet.fromSetUnsafe(nes.toSortedSet)))
}
}

Expand All @@ -199,32 +199,32 @@ class NonEmptySetSuite extends CatsSuite {

test("+ consistent with Set") {
forAll { (nes: NonEmptySet[Int], i: Int) =>
(nes + i).toSet should === (nes.toSet + i)
(nes + i).toSortedSet should === (nes.toSortedSet + i)
}
}

test("NonEmptySet#zipWithIndex is consistent with Set#zipWithIndex") {
forAll { nes: NonEmptySet[Int] =>
nes.zipWithIndex.toSet should === (nes.toSet.zipWithIndex)
nes.zipWithIndex.toSortedSet should === (nes.toSortedSet.zipWithIndex)
}
}

test("NonEmptySet#size and length is consistent with Set#size") {
forAll { nes: NonEmptySet[Int] =>
nes.size should === (nes.toSet.size)
nes.length should === (nes.toSet.size)
nes.size should === (nes.toSortedSet.size)
nes.length should === (nes.toSortedSet.size)
}
}

test("NonEmptySet#concat is consistent with Set#++") {
forAll { (nes: NonEmptySet[Int], l: SortedSet[Int], n: Int) =>
nes.concat(NonEmptySet(n, l)).toSet should === (nes.toSet ++ (l + n))
nes.union(NonEmptySet(n, l)).toSortedSet should === (nes.toSortedSet ++ (l + n))
}
}

test("NonEmptySet#zipWith is consistent with Set#zip and then Set#map") {
forAll { (a: NonEmptySet[Int], b: NonEmptySet[Int], f: (Int, Int) => Int) =>
a.zipWith(b)(f).toSet should ===(a.toSet.zip(b.toSet).map { case (x, y) => f(x, y) })
a.zipWith(b)(f).toSortedSet should ===(a.toSortedSet.zip(b.toSortedSet).map { case (x, y) => f(x, y) })
}
}

Expand Down

0 comments on commit 34aa71d

Please sign in to comment.