From 7fc599457eab32ada093f455428aafba030f95ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gutowski?= Date: Sun, 14 Oct 2018 22:46:37 +0200 Subject: [PATCH 1/5] Add NonEmptyList#toNes (issue #2346) --- core/src/main/scala/cats/data/NonEmptyList.scala | 13 +++++++++++++ .../test/scala/cats/tests/NonEmptyListSuite.scala | 9 ++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/data/NonEmptyList.scala b/core/src/main/scala/cats/data/NonEmptyList.scala index 15315d7f38..6570fc2d21 100644 --- a/core/src/main/scala/cats/data/NonEmptyList.scala +++ b/core/src/main/scala/cats/data/NonEmptyList.scala @@ -421,6 +421,19 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { */ def toNem[T, U](implicit ev: A <:< (T, U), order: Order[T]): NonEmptyMap[T, U] = NonEmptyMap.fromMapUnsafe(SortedMap(toList.map(ev): _*)(order.toOrdering)) + + /** + * Creates new `NonEmptySet`, similarly to List#toSet from scala standard library. + *{{{ + * scala> import cats.data._ + * scala> import cats.instances.int._ + * scala> val nel = NonEmptyList(1, List(2,2,3,4)) + * scala> nel.toNes + * res0: cats.data.NonEmptySet[Int] = TreeSet(1, 2, 3, 4) + *}}} + */ + def toNes[B >: A](implicit order: Order[B]): NonEmptySet[B] = + NonEmptySet.of(head, tail :_*) } object NonEmptyList extends NonEmptyListInstances { diff --git a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala index 948dac307c..569f638740 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala @@ -3,11 +3,12 @@ package tests import cats.kernel.laws.discipline.{SemigroupTests, OrderTests, PartialOrderTests, EqTests} -import cats.data.{NonEmptyList, NonEmptyVector, NonEmptyMap} +import cats.data.{NonEmptyList, NonEmptyVector, NonEmptyMap, NonEmptySet} import cats.data.NonEmptyList.ZipNonEmptyList import cats.laws.discipline.arbitrary._ import cats.laws.discipline.{CommutativeApplyTests, BimonadTests, NonEmptyTraverseTests, ReducibleTests, SemigroupKTests, SerializableTests} import scala.collection.immutable.SortedMap +import scala.collection.immutable.SortedSet class NonEmptyListSuite extends CatsSuite { // Lots of collections here.. telling ScalaCheck to calm down a bit @@ -322,6 +323,12 @@ class NonEmptyListSuite extends CatsSuite { nel.toNem should ===(NonEmptyMap.fromMapUnsafe(SortedMap.empty[Int, String] ++ nel.toList.toMap)) } } + + test("NonEmptyList#toNes is consistent with List#toSet and creating NonEmptySet from it") { + forAll { nel: NonEmptyList[Int] => + nel.toNes should ===(NonEmptySet.fromSetUnsafe(SortedSet.empty[Int] ++ nel.toList.toSet)) + } + } } @deprecated("to be able to test deprecated methods", since = "1.0.0-RC1") From d6d3dcae5b2db3af77ce3814323f5887529a733b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gutowski?= Date: Tue, 23 Oct 2018 07:57:56 +0200 Subject: [PATCH 2/5] Fixed NonEmptyList.scala formating --- .../main/scala/cats/data/NonEmptyList.scala | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/main/scala/cats/data/NonEmptyList.scala b/core/src/main/scala/cats/data/NonEmptyList.scala index a74afc0de1..2bb0d2842b 100644 --- a/core/src/main/scala/cats/data/NonEmptyList.scala +++ b/core/src/main/scala/cats/data/NonEmptyList.scala @@ -419,17 +419,17 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { NonEmptyMap.fromMapUnsafe(SortedMap(toList.map(ev): _*)(order.toOrdering)) /** - * Creates new `NonEmptySet`, similarly to List#toSet from scala standard library. - *{{{ - * scala> import cats.data._ - * scala> import cats.instances.int._ - * scala> val nel = NonEmptyList(1, List(2,2,3,4)) - * scala> nel.toNes - * res0: cats.data.NonEmptySet[Int] = TreeSet(1, 2, 3, 4) - *}}} - */ + * Creates new `NonEmptySet`, similarly to List#toSet from scala standard library. + *{{{ + * scala> import cats.data._ + * scala> import cats.instances.int._ + * scala> val nel = NonEmptyList(1, List(2,2,3,4)) + * scala> nel.toNes + * res0: cats.data.NonEmptySet[Int] = TreeSet(1, 2, 3, 4) + *}}} + */ def toNes[B >: A](implicit order: Order[B]): NonEmptySet[B] = - NonEmptySet.of(head, tail :_*) + NonEmptySet.of(head, tail: _*) } object NonEmptyList extends NonEmptyListInstances { From 1a4ff0d7c24b697b0600784aaf0a6f1813bb61c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gutowski?= Date: Tue, 23 Oct 2018 18:27:04 +0200 Subject: [PATCH 3/5] Fixed NonEmptyListSuite.scala formating --- .../scala/cats/tests/NonEmptyListSuite.scala | 50 +++++++------------ 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala index 7b79273684..b56c2d9ff2 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala @@ -3,7 +3,7 @@ package tests import cats.kernel.laws.discipline.{EqTests, OrderTests, PartialOrderTests, SemigroupTests} -import cats.data.{NonEmptyList, NonEmptyVector, NonEmptyMap, NonEmptySet} +import cats.data.{NonEmptyList, NonEmptyMap, NonEmptySet, NonEmptyVector} import cats.data.NonEmptyList.ZipNonEmptyList import cats.laws.discipline.arbitrary._ import cats.laws.discipline.{ @@ -159,21 +159,18 @@ class NonEmptyListSuite extends CatsSuite { } test("reduce consistent with fold") { - forAll { (nel: NonEmptyList[Int]) => - nel.reduce should ===(nel.fold) + forAll { (nel: NonEmptyList[Int]) => nel.reduce should ===(nel.fold) } } test("reduce consistent with reduceK") { - forAll { (nel: NonEmptyList[Option[Int]]) => - nel.reduce(SemigroupK[Option].algebra[Int]) should ===(nel.reduceK) + forAll { (nel: NonEmptyList[Option[Int]]) => nel.reduce(SemigroupK[Option].algebra[Int]) should ===(nel.reduceK) } } test("reduceLeftToOption consistent with foldLeft + Option") { forAll { (nel: NonEmptyList[Int], f: Int => String, g: (String, Int) => String) => - val expected = nel.tail.foldLeft(Option(f(nel.head))) { (opt, i) => - opt.map(s => g(s, i)) + val expected = nel.tail.foldLeft(Option(f(nel.head))) { (opt, i) => opt.map(s => g(s, i)) } nel.reduceLeftToOption(f)(g) should ===(expected) } @@ -183,8 +180,7 @@ class NonEmptyListSuite extends CatsSuite { forAll { (nel: NonEmptyList[Int], f: Int => String, g: (Int, Eval[String]) => Eval[String]) => val got = nel.reduceRightToOption(f)(g).value val last :: rev = nel.toList.reverse - val expected = rev.reverse.foldRight(Option(f(last))) { (i, opt) => - opt.map(s => g(i, Now(s)).value) + val expected = rev.reverse.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) } got should ===(expected) } @@ -193,26 +189,22 @@ class NonEmptyListSuite extends CatsSuite { test("reduceLeftM consistent with foldM") { forAll { (nel: NonEmptyList[Int], f: Int => Option[Int]) => val got = nel.reduceLeftM(f)((acc, i) => f(i).map(acc + _)) - val expected = f(nel.head).flatMap { hd => - nel.tail.foldM(hd)((acc, i) => f(i).map(acc + _)) + val expected = f(nel.head).flatMap { hd => nel.tail.foldM(hd)((acc, i) => f(i).map(acc + _)) } got should ===(expected) } } test("reduceMapM consistent with foldMapM") { - forAll { (nel: NonEmptyList[Int], f: Int => Option[Int]) => - nel.reduceMapM(f) should ===(nel.foldMapM(f)) + forAll { (nel: NonEmptyList[Int], f: Int => Option[Int]) => nel.reduceMapM(f) should ===(nel.foldMapM(f)) } } test("fromList round trip") { - forAll { l: List[Int] => - NonEmptyList.fromList(l).map(_.toList).getOrElse(List.empty) should ===(l) + forAll { l: List[Int] => NonEmptyList.fromList(l).map(_.toList).getOrElse(List.empty) should ===(l) } - forAll { nel: NonEmptyList[Int] => - NonEmptyList.fromList(nel.toList) should ===(Some(nel)) + forAll { nel: NonEmptyList[Int] => NonEmptyList.fromList(nel.toList) should ===(Some(nel)) } } @@ -236,32 +228,27 @@ class NonEmptyListSuite extends CatsSuite { } test("NonEmptyList#distinct is consistent with List#distinct") { - forAll { nel: NonEmptyList[Int] => - nel.distinct.toList should ===(nel.toList.distinct) + forAll { nel: NonEmptyList[Int] => nel.distinct.toList should ===(nel.toList.distinct) } } test("NonEmptyList#reverse is consistent with List#reverse") { - forAll { nel: NonEmptyList[Int] => - nel.reverse.toList should ===(nel.toList.reverse) + forAll { nel: NonEmptyList[Int] => nel.reverse.toList should ===(nel.toList.reverse) } } test("NonEmptyList#zipWithIndex is consistent with List#zipWithIndex") { - forAll { nel: NonEmptyList[Int] => - nel.zipWithIndex.toList should ===(nel.toList.zipWithIndex) + forAll { nel: NonEmptyList[Int] => nel.zipWithIndex.toList should ===(nel.toList.zipWithIndex) } } test("NonEmptyList#last is consistent with List#last") { - forAll { nel: NonEmptyList[Int] => - nel.last should ===(nel.toList.last) + forAll { nel: NonEmptyList[Int] => nel.last should ===(nel.toList.last) } } test("NonEmptyList#init is consistent with List#init") { - forAll { nel: NonEmptyList[Int] => - nel.init should ===(nel.toList.init) + forAll { nel: NonEmptyList[Int] => nel.init should ===(nel.toList.init) } } @@ -273,14 +260,12 @@ class NonEmptyListSuite extends CatsSuite { } test("NonEmptyList#sorted is consistent with List#sorted") { - forAll { nel: NonEmptyList[Int] => - nel.sorted.toList should ===(nel.toList.sorted) + forAll { nel: NonEmptyList[Int] => nel.sorted.toList should ===(nel.toList.sorted) } } test("NonEmptyList#sortBy is consistent with List#sortBy") { - forAll { (nel: NonEmptyList[Int], f: Int => Int) => - nel.sortBy(f).toList should ===(nel.toList.sortBy(f)) + forAll { (nel: NonEmptyList[Int], f: Int => Int) => nel.sortBy(f).toList should ===(nel.toList.sortBy(f)) } } @@ -299,8 +284,7 @@ class NonEmptyListSuite extends CatsSuite { } test("NonEmptyList#fromFoldabale is consistent with NonEmptyList#fromList") { - forAll { (xs: List[Int]) => - NonEmptyList.fromList(xs) should ===(NonEmptyList.fromFoldable(xs)) + forAll { (xs: List[Int]) => NonEmptyList.fromList(xs) should ===(NonEmptyList.fromFoldable(xs)) } } From 5d365ff9c8dce66dbe87598701103b8d9e17c2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gutowski?= Date: Tue, 23 Oct 2018 22:13:29 +0200 Subject: [PATCH 4/5] Revert "Fixed NonEmptyListSuite.scala formating" This reverts commit 1a4ff0d7c24b697b0600784aaf0a6f1813bb61c3. --- .../scala/cats/tests/NonEmptyListSuite.scala | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala index b56c2d9ff2..7b79273684 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala @@ -3,7 +3,7 @@ package tests import cats.kernel.laws.discipline.{EqTests, OrderTests, PartialOrderTests, SemigroupTests} -import cats.data.{NonEmptyList, NonEmptyMap, NonEmptySet, NonEmptyVector} +import cats.data.{NonEmptyList, NonEmptyVector, NonEmptyMap, NonEmptySet} import cats.data.NonEmptyList.ZipNonEmptyList import cats.laws.discipline.arbitrary._ import cats.laws.discipline.{ @@ -159,18 +159,21 @@ class NonEmptyListSuite extends CatsSuite { } test("reduce consistent with fold") { - forAll { (nel: NonEmptyList[Int]) => nel.reduce should ===(nel.fold) + forAll { (nel: NonEmptyList[Int]) => + nel.reduce should ===(nel.fold) } } test("reduce consistent with reduceK") { - forAll { (nel: NonEmptyList[Option[Int]]) => nel.reduce(SemigroupK[Option].algebra[Int]) should ===(nel.reduceK) + forAll { (nel: NonEmptyList[Option[Int]]) => + nel.reduce(SemigroupK[Option].algebra[Int]) should ===(nel.reduceK) } } test("reduceLeftToOption consistent with foldLeft + Option") { forAll { (nel: NonEmptyList[Int], f: Int => String, g: (String, Int) => String) => - val expected = nel.tail.foldLeft(Option(f(nel.head))) { (opt, i) => opt.map(s => g(s, i)) + val expected = nel.tail.foldLeft(Option(f(nel.head))) { (opt, i) => + opt.map(s => g(s, i)) } nel.reduceLeftToOption(f)(g) should ===(expected) } @@ -180,7 +183,8 @@ class NonEmptyListSuite extends CatsSuite { forAll { (nel: NonEmptyList[Int], f: Int => String, g: (Int, Eval[String]) => Eval[String]) => val got = nel.reduceRightToOption(f)(g).value val last :: rev = nel.toList.reverse - val expected = rev.reverse.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) + val expected = rev.reverse.foldRight(Option(f(last))) { (i, opt) => + opt.map(s => g(i, Now(s)).value) } got should ===(expected) } @@ -189,22 +193,26 @@ class NonEmptyListSuite extends CatsSuite { test("reduceLeftM consistent with foldM") { forAll { (nel: NonEmptyList[Int], f: Int => Option[Int]) => val got = nel.reduceLeftM(f)((acc, i) => f(i).map(acc + _)) - val expected = f(nel.head).flatMap { hd => nel.tail.foldM(hd)((acc, i) => f(i).map(acc + _)) + val expected = f(nel.head).flatMap { hd => + nel.tail.foldM(hd)((acc, i) => f(i).map(acc + _)) } got should ===(expected) } } test("reduceMapM consistent with foldMapM") { - forAll { (nel: NonEmptyList[Int], f: Int => Option[Int]) => nel.reduceMapM(f) should ===(nel.foldMapM(f)) + forAll { (nel: NonEmptyList[Int], f: Int => Option[Int]) => + nel.reduceMapM(f) should ===(nel.foldMapM(f)) } } test("fromList round trip") { - forAll { l: List[Int] => NonEmptyList.fromList(l).map(_.toList).getOrElse(List.empty) should ===(l) + forAll { l: List[Int] => + NonEmptyList.fromList(l).map(_.toList).getOrElse(List.empty) should ===(l) } - forAll { nel: NonEmptyList[Int] => NonEmptyList.fromList(nel.toList) should ===(Some(nel)) + forAll { nel: NonEmptyList[Int] => + NonEmptyList.fromList(nel.toList) should ===(Some(nel)) } } @@ -228,27 +236,32 @@ class NonEmptyListSuite extends CatsSuite { } test("NonEmptyList#distinct is consistent with List#distinct") { - forAll { nel: NonEmptyList[Int] => nel.distinct.toList should ===(nel.toList.distinct) + forAll { nel: NonEmptyList[Int] => + nel.distinct.toList should ===(nel.toList.distinct) } } test("NonEmptyList#reverse is consistent with List#reverse") { - forAll { nel: NonEmptyList[Int] => nel.reverse.toList should ===(nel.toList.reverse) + forAll { nel: NonEmptyList[Int] => + nel.reverse.toList should ===(nel.toList.reverse) } } test("NonEmptyList#zipWithIndex is consistent with List#zipWithIndex") { - forAll { nel: NonEmptyList[Int] => nel.zipWithIndex.toList should ===(nel.toList.zipWithIndex) + forAll { nel: NonEmptyList[Int] => + nel.zipWithIndex.toList should ===(nel.toList.zipWithIndex) } } test("NonEmptyList#last is consistent with List#last") { - forAll { nel: NonEmptyList[Int] => nel.last should ===(nel.toList.last) + forAll { nel: NonEmptyList[Int] => + nel.last should ===(nel.toList.last) } } test("NonEmptyList#init is consistent with List#init") { - forAll { nel: NonEmptyList[Int] => nel.init should ===(nel.toList.init) + forAll { nel: NonEmptyList[Int] => + nel.init should ===(nel.toList.init) } } @@ -260,12 +273,14 @@ class NonEmptyListSuite extends CatsSuite { } test("NonEmptyList#sorted is consistent with List#sorted") { - forAll { nel: NonEmptyList[Int] => nel.sorted.toList should ===(nel.toList.sorted) + forAll { nel: NonEmptyList[Int] => + nel.sorted.toList should ===(nel.toList.sorted) } } test("NonEmptyList#sortBy is consistent with List#sortBy") { - forAll { (nel: NonEmptyList[Int], f: Int => Int) => nel.sortBy(f).toList should ===(nel.toList.sortBy(f)) + forAll { (nel: NonEmptyList[Int], f: Int => Int) => + nel.sortBy(f).toList should ===(nel.toList.sortBy(f)) } } @@ -284,7 +299,8 @@ class NonEmptyListSuite extends CatsSuite { } test("NonEmptyList#fromFoldabale is consistent with NonEmptyList#fromList") { - forAll { (xs: List[Int]) => NonEmptyList.fromList(xs) should ===(NonEmptyList.fromFoldable(xs)) + forAll { (xs: List[Int]) => + NonEmptyList.fromList(xs) should ===(NonEmptyList.fromFoldable(xs)) } } From 636f6f66e80e08aa88bbbd19d87148efb5e73f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gutowski?= Date: Tue, 23 Oct 2018 22:34:06 +0200 Subject: [PATCH 5/5] Fixed NonEmptyListSuite.scala formating, this time for sure --- tests/src/test/scala/cats/tests/NonEmptyListSuite.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala index 7b79273684..e3d21e049c 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala @@ -3,7 +3,7 @@ package tests import cats.kernel.laws.discipline.{EqTests, OrderTests, PartialOrderTests, SemigroupTests} -import cats.data.{NonEmptyList, NonEmptyVector, NonEmptyMap, NonEmptySet} +import cats.data.{NonEmptyList, NonEmptyMap, NonEmptySet, NonEmptyVector} import cats.data.NonEmptyList.ZipNonEmptyList import cats.laws.discipline.arbitrary._ import cats.laws.discipline.{