From 0fb07ab4ba0364a31f5d6e15c8128f4cda5e9651 Mon Sep 17 00:00:00 2001 From: Leandro Galvan Date: Fri, 21 Sep 2018 22:32:52 -0300 Subject: [PATCH 1/4] Add count_ as syntax to UnorderedFoldable --- core/src/main/scala/cats/implicits.scala | 1 + core/src/main/scala/cats/syntax/all.scala | 4 +++ .../scala/cats/syntax/unorderedFoldable.scala | 33 +++++++++++++++++++ .../src/main/scala/cats/tests/CatsSuite.scala | 4 +-- .../cats/tests/UnorderedFoldableSuite.scala | 26 +++++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 core/src/main/scala/cats/syntax/unorderedFoldable.scala create mode 100644 tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala diff --git a/core/src/main/scala/cats/implicits.scala b/core/src/main/scala/cats/implicits.scala index d89f1f1d46..01f3c3e6cc 100644 --- a/core/src/main/scala/cats/implicits.scala +++ b/core/src/main/scala/cats/implicits.scala @@ -5,6 +5,7 @@ object implicits with syntax.AllSyntaxBinCompat0 with syntax.AllSyntaxBinCompat1 with syntax.AllSyntaxBinCompat2 + with syntax.AllSyntaxBinCompat3 with instances.AllInstances with instances.AllInstancesBinCompat0 with instances.AllInstancesBinCompat1 diff --git a/core/src/main/scala/cats/syntax/all.scala b/core/src/main/scala/cats/syntax/all.scala index dd270b7ef5..749e4a8619 100644 --- a/core/src/main/scala/cats/syntax/all.scala +++ b/core/src/main/scala/cats/syntax/all.scala @@ -6,6 +6,7 @@ abstract class AllSyntaxBinCompat with AllSyntaxBinCompat0 with AllSyntaxBinCompat1 with AllSyntaxBinCompat2 + with AllSyntaxBinCompat3 trait AllSyntax extends AlternativeSyntax @@ -77,3 +78,6 @@ trait AllSyntaxBinCompat2 with EitherSyntaxBinCompat0 with ListSyntaxBinCompat0 with ValidatedSyntaxBincompat0 + +trait AllSyntaxBinCompat3 + extends UnorderedFoldableSyntax diff --git a/core/src/main/scala/cats/syntax/unorderedFoldable.scala b/core/src/main/scala/cats/syntax/unorderedFoldable.scala new file mode 100644 index 0000000000..0b0d18c8fb --- /dev/null +++ b/core/src/main/scala/cats/syntax/unorderedFoldable.scala @@ -0,0 +1,33 @@ +package cats +package syntax + +import cats.instances.long._ + +trait UnorderedFoldableSyntax extends UnorderedFoldable.ToUnorderedFoldableOps { + implicit final def catsSyntaxUnorderedFoldableOps[F[_]: UnorderedFoldable, A](fa: F[A]): UnorderedFoldableOps[F, A] = + new UnorderedFoldableOps[F, A](fa) +} + +final class UnorderedFoldableOps[F[_], A](val fa: F[A]) extends AnyVal { + /** + * Count the number of elements in the structure that satisfy the given predicate. + * + * For example: + * {{{ + * scala> import cats.implicits._ + * scala> val set1 = Set[String]() + * scala> set1.count_(_.length > 0) + * res0: Long = 0 + * + * scala> val set2 = Set("hello", "world", "!") + * scala> set2.count_(_.length > 1) + * res1: Long = 2 + * + * scala> val set3 = Set(41, 32, 23) + * scala> set3.count_(_ % 2 == 0) + * res2: Long = 1 + * }}} + */ + def count_(p: A => Boolean)(implicit F: UnorderedFoldable[F]): Long = + F.unorderedFoldMap(fa)(a => if (p(a)) 1L else 0L) +} diff --git a/testkit/src/main/scala/cats/tests/CatsSuite.scala b/testkit/src/main/scala/cats/tests/CatsSuite.scala index fac621f4dd..40fb21bcf9 100644 --- a/testkit/src/main/scala/cats/tests/CatsSuite.scala +++ b/testkit/src/main/scala/cats/tests/CatsSuite.scala @@ -3,7 +3,7 @@ package tests import catalysts.Platform import cats.instances.{AllInstances, AllInstancesBinCompat0, AllInstancesBinCompat1} -import cats.syntax.{AllSyntax, AllSyntaxBinCompat0, AllSyntaxBinCompat1, AllSyntaxBinCompat2, EqOps} +import cats.syntax.{AllSyntax, AllSyntaxBinCompat0, AllSyntaxBinCompat1, AllSyntaxBinCompat2, AllSyntaxBinCompat3, EqOps} import org.scalactic.anyvals.{PosInt, PosZDouble, PosZInt} import org.scalatest.{FunSuite, FunSuiteLike, Matchers} import org.scalatest.prop.{Configuration, GeneratorDrivenPropertyChecks} @@ -35,7 +35,7 @@ trait CatsSuite extends FunSuite with TestSettings with AllInstances with AllInstancesBinCompat0 with AllInstancesBinCompat1 with AllSyntax with AllSyntaxBinCompat0 with AllSyntaxBinCompat1 - with AllSyntaxBinCompat2 + with AllSyntaxBinCompat2 with AllSyntaxBinCompat3 with StrictCatsEquality { self: FunSuiteLike => implicit override val generatorDrivenConfig: PropertyCheckConfiguration = diff --git a/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala b/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala new file mode 100644 index 0000000000..d4ca94a873 --- /dev/null +++ b/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala @@ -0,0 +1,26 @@ +package cats +package tests + +import org.scalatest.prop.PropertyChecks +import org.scalacheck.Arbitrary +import cats.instances.all._ + +abstract class UnorderedFoldableSuite[F[_]: UnorderedFoldable](name: String)( + implicit ArbFString: Arbitrary[F[String]]) extends CatsSuite with PropertyChecks { + + def iterator[T](fa: F[T]): Iterator[T] + + test(s"UnorderedFoldable[$name].count") { + forAll { (fa: F[String], p: String => Boolean) => + fa.count_(p) === iterator(fa).count(p).toLong + } + } +} + +class UnorderedFoldableSetSuite extends UnorderedFoldableSuite[Set]("set") { + def iterator[T](set: Set[T]): Iterator[T] = set.iterator +} + +class UnorderedFoldableMapSuite extends UnorderedFoldableSuite[Map[String, ?]]("map") { + def iterator[T](map: Map[String, T]): Iterator[T] = map.valuesIterator +} \ No newline at end of file From 86807b7e94e196ca44e6c0120c251059734fe92f Mon Sep 17 00:00:00 2001 From: Leandro Galvan Date: Sat, 22 Sep 2018 18:00:31 -0300 Subject: [PATCH 2/4] Change method name count_ to count in UnorderedFoldable --- .../scala/cats/syntax/unorderedFoldable.scala | 16 +++++++--------- .../cats/tests/UnorderedFoldableSuite.scala | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/core/src/main/scala/cats/syntax/unorderedFoldable.scala b/core/src/main/scala/cats/syntax/unorderedFoldable.scala index 0b0d18c8fb..cde4104c91 100644 --- a/core/src/main/scala/cats/syntax/unorderedFoldable.scala +++ b/core/src/main/scala/cats/syntax/unorderedFoldable.scala @@ -15,19 +15,17 @@ final class UnorderedFoldableOps[F[_], A](val fa: F[A]) extends AnyVal { * For example: * {{{ * scala> import cats.implicits._ - * scala> val set1 = Set[String]() - * scala> set1.count_(_.length > 0) + * scala> val map1 = Map[Int, String]() + * scala> val p1: String => Boolean = _.length > 0 + * scala> map1.count(p1) * res0: Long = 0 * - * scala> val set2 = Set("hello", "world", "!") - * scala> set2.count_(_.length > 1) + * scala> val map2 = Map(1 -> "hello", 2 -> "world", 3 -> "!") + * scala> val p2: String => Boolean = _.length > 1 + * scala> map2.count(p2) * res1: Long = 2 - * - * scala> val set3 = Set(41, 32, 23) - * scala> set3.count_(_ % 2 == 0) - * res2: Long = 1 * }}} */ - def count_(p: A => Boolean)(implicit F: UnorderedFoldable[F]): Long = + def count(p: A => Boolean)(implicit F: UnorderedFoldable[F]): Long = F.unorderedFoldMap(fa)(a => if (p(a)) 1L else 0L) } diff --git a/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala b/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala index d4ca94a873..a0bd683c1c 100644 --- a/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala +++ b/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala @@ -12,7 +12,7 @@ abstract class UnorderedFoldableSuite[F[_]: UnorderedFoldable](name: String)( test(s"UnorderedFoldable[$name].count") { forAll { (fa: F[String], p: String => Boolean) => - fa.count_(p) === iterator(fa).count(p).toLong + fa.count(p) === iterator(fa).count(p).toLong } } } From e5737430fdb25c7ae915308e4ce97dd371d37b56 Mon Sep 17 00:00:00 2001 From: Leandro Galvan Date: Sat, 22 Sep 2018 18:50:05 -0300 Subject: [PATCH 3/4] Fire travis build From f0ef0698a404a7b3945f04ad495d3ad649cab806 Mon Sep 17 00:00:00 2001 From: Leandro Galvan Date: Sun, 23 Sep 2018 15:04:07 -0300 Subject: [PATCH 4/4] Add unorederedFoldable to syntax package object --- core/src/main/scala/cats/syntax/package.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/scala/cats/syntax/package.scala b/core/src/main/scala/cats/syntax/package.scala index 771706bee0..b00ab4373e 100644 --- a/core/src/main/scala/cats/syntax/package.scala +++ b/core/src/main/scala/cats/syntax/package.scala @@ -52,6 +52,7 @@ package object syntax { object traverse extends TraverseSyntax object traverseFilter extends TraverseFilterSyntax object nonEmptyTraverse extends NonEmptyTraverseSyntax + object unorderedFoldable extends UnorderedFoldableSyntax object unorderedTraverse extends UnorderedTraverseSyntax object validated extends ValidatedSyntax with ValidatedExtensionSyntax with ValidatedSyntaxBincompat0 object vector extends VectorSyntax