From 2d5f4d7917804e921488f5f2e263e8349a6ceb42 Mon Sep 17 00:00:00 2001 From: Tim Spence Date: Wed, 13 Dec 2023 15:58:20 +0000 Subject: [PATCH] Implement optimized traverseFilter in terms of Chain as well --- core/src/main/scala-2.13+/cats/instances/arraySeq.scala | 2 +- core/src/main/scala/cats/TraverseFilter.scala | 6 +++--- core/src/main/scala/cats/data/Chain.scala | 2 +- core/src/main/scala/cats/instances/queue.scala | 2 +- core/src/main/scala/cats/instances/seq.scala | 2 +- core/src/main/scala/cats/instances/vector.scala | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/scala-2.13+/cats/instances/arraySeq.scala b/core/src/main/scala-2.13+/cats/instances/arraySeq.scala index 4bfc923b87..cc254fbcae 100644 --- a/core/src/main/scala-2.13+/cats/instances/arraySeq.scala +++ b/core/src/main/scala-2.13+/cats/instances/arraySeq.scala @@ -234,7 +234,7 @@ private[cats] object ArraySeqInstances { G match { case x: StackSafeMonad[G] => x.map(TraverseFilter.traverseFilterDirectly(fa.iterator)(f)(x))( - _.to(ArraySeq.untagged) + _.iterator.to(ArraySeq.untagged) ) case _ => fa.foldRight(Eval.now(G.pure(ArraySeq.untagged.empty[B]))) { case (x, xse) => diff --git a/core/src/main/scala/cats/TraverseFilter.scala b/core/src/main/scala/cats/TraverseFilter.scala index 0f15703df8..0907ef3be7 100644 --- a/core/src/main/scala/cats/TraverseFilter.scala +++ b/core/src/main/scala/cats/TraverseFilter.scala @@ -21,7 +21,7 @@ package cats -import cats.data.State +import cats.data.{Chain, State} import cats.kernel.compat.scalaVersionSpecific._ import scala.collection.immutable.{IntMap, TreeSet} @@ -206,8 +206,8 @@ object TraverseFilter { private[cats] def traverseFilterDirectly[G[_], A, B]( fa: IterableOnce[A] - )(f: A => G[Option[B]])(implicit G: StackSafeMonad[G]): G[Vector[B]] = { - fa.iterator.foldLeft(G.pure(Vector.empty[B])) { case (bldrG, a) => + )(f: A => G[Option[B]])(implicit G: StackSafeMonad[G]): G[Chain[B]] = { + fa.iterator.foldLeft(G.pure(Chain.empty[B])) { case (bldrG, a) => G.map2(bldrG, f(a)) { case (acc, Some(b)) => acc :+ b case (acc, None) => acc diff --git a/core/src/main/scala/cats/data/Chain.scala b/core/src/main/scala/cats/data/Chain.scala index 28b32cd577..e113cae684 100644 --- a/core/src/main/scala/cats/data/Chain.scala +++ b/core/src/main/scala/cats/data/Chain.scala @@ -1372,7 +1372,7 @@ sealed abstract private[data] class ChainInstances extends ChainInstances1 { else G match { case x: StackSafeMonad[G] => - G.map(TraverseFilter.traverseFilterDirectly(fa.iterator)(f)(x))(Chain.fromSeq(_)) + TraverseFilter.traverseFilterDirectly(fa.iterator)(f)(x) case _ => traverseFilterViaChain { val as = collection.mutable.ArrayBuffer[A]() diff --git a/core/src/main/scala/cats/instances/queue.scala b/core/src/main/scala/cats/instances/queue.scala index 3c7b2a9633..05bd98f8b7 100644 --- a/core/src/main/scala/cats/instances/queue.scala +++ b/core/src/main/scala/cats/instances/queue.scala @@ -241,7 +241,7 @@ private object QueueInstances { else G match { case x: StackSafeMonad[G] => - x.map(TraverseFilter.traverseFilterDirectly(fa)(f)(x))(traverse.fromIterableOnce(_)) + x.map(TraverseFilter.traverseFilterDirectly(fa)(f)(x))(c => traverse.fromIterableOnce(c.iterator)) case _ => G.map(Chain.traverseFilterViaChain { val as = collection.mutable.ArrayBuffer[A]() diff --git a/core/src/main/scala/cats/instances/seq.scala b/core/src/main/scala/cats/instances/seq.scala index 18ba3f8688..0ad0005575 100644 --- a/core/src/main/scala/cats/instances/seq.scala +++ b/core/src/main/scala/cats/instances/seq.scala @@ -210,7 +210,7 @@ trait SeqInstances extends cats.kernel.instances.SeqInstances { def traverseFilter[G[_], A, B](fa: Seq[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Seq[B]] = G match { - case x: StackSafeMonad[G] => x.map(TraverseFilter.traverseFilterDirectly(fa)(f)(x))(_.toSeq) + case x: StackSafeMonad[G] => x.map(TraverseFilter.traverseFilterDirectly(fa)(f)(x))(_.toVector) case _ => G.map(Chain.traverseFilterViaChain(fa.toIndexedSeq)(f))(_.toVector) } diff --git a/core/src/main/scala/cats/instances/vector.scala b/core/src/main/scala/cats/instances/vector.scala index b927ede1f1..06f93b4fef 100644 --- a/core/src/main/scala/cats/instances/vector.scala +++ b/core/src/main/scala/cats/instances/vector.scala @@ -271,7 +271,7 @@ private[instances] trait VectorInstancesBinCompat0 { def traverseFilter[G[_], A, B](fa: Vector[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Vector[B]] = G match { - case x: StackSafeMonad[G] => TraverseFilter.traverseFilterDirectly(fa)(f)(x) + case x: StackSafeMonad[G] => x.map(TraverseFilter.traverseFilterDirectly(fa)(f)(x))(_.toVector) case _ => G.map(Chain.traverseFilterViaChain(fa)(f))(_.toVector) }