From c541f7715948600d3ed20e2e09c88c4095b12b5b Mon Sep 17 00:00:00 2001 From: Kalra Date: Tue, 11 Feb 2020 19:45:15 +0800 Subject: [PATCH] backported #3103 Add traverseFilter instances for Queue --- core/src/main/scala/cats/instances/all.scala | 1 + .../src/main/scala/cats/instances/queue.scala | 29 +++++++++++++++++++ .../test/scala/cats/tests/QueueSuite.scala | 5 +++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/instances/all.scala b/core/src/main/scala/cats/instances/all.scala index 5dcc1a3e02..0f2c2c8d55 100644 --- a/core/src/main/scala/cats/instances/all.scala +++ b/core/src/main/scala/cats/instances/all.scala @@ -69,3 +69,4 @@ trait AllInstancesBinCompat7 with VectorInstancesBinCompat1 with EitherInstancesBinCompat0 with StreamInstancesBinCompat1 + with QueueInstancesBinCompat0 diff --git a/core/src/main/scala/cats/instances/queue.scala b/core/src/main/scala/cats/instances/queue.scala index aebedd10de..9a898afa39 100644 --- a/core/src/main/scala/cats/instances/queue.scala +++ b/core/src/main/scala/cats/instances/queue.scala @@ -2,6 +2,7 @@ package cats package instances import cats.syntax.show._ + import scala.annotation.tailrec import scala.collection.immutable.Queue import scala.util.Try @@ -153,3 +154,31 @@ trait QueueInstances extends cats.kernel.instances.QueueInstances { fa.iterator.map(_.show).mkString("Queue(", ", ", ")") } } + +private[instances] trait QueueInstancesBinCompat0 { + implicit val catsStdTraverseFilterForQueue: TraverseFilter[Queue] = new TraverseFilter[Queue] { + val traverse: Traverse[Queue] = cats.instances.queue.catsStdInstancesForQueue + + override def mapFilter[A, B](fa: Queue[A])(f: (A) => Option[B]): Queue[B] = + fa.collect(Function.unlift(f)) + + override def filter[A](fa: Queue[A])(f: (A) => Boolean): Queue[A] = fa.filter(f) + + override def collect[A, B](fa: Queue[A])(f: PartialFunction[A, B]): Queue[B] = fa.collect(f) + + override def flattenOption[A](fa: Queue[Option[A]]): Queue[A] = fa.flatten + + def traverseFilter[G[_], A, B](fa: Queue[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Queue[B]] = + fa.foldRight(Eval.now(G.pure(Queue.empty[B])))( + (x, xse) => G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ +: o)) + ) + .value + + override def filterA[G[_], A](fa: Queue[A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[Queue[A]] = + fa.foldRight(Eval.now(G.pure(Queue.empty[A])))( + (x, xse) => G.map2Eval(f(x), xse)((b, vec) => if (b) x +: vec else vec) + ) + .value + } + +} diff --git a/tests/src/test/scala/cats/tests/QueueSuite.scala b/tests/src/test/scala/cats/tests/QueueSuite.scala index a632022465..255adc0f6f 100644 --- a/tests/src/test/scala/cats/tests/QueueSuite.scala +++ b/tests/src/test/scala/cats/tests/QueueSuite.scala @@ -2,13 +2,13 @@ package cats package tests import scala.collection.immutable.Queue - import cats.laws.discipline.{ AlternativeTests, CoflatMapTests, MonadTests, SemigroupalTests, SerializableTests, + TraverseFilterTests, TraverseTests } @@ -28,6 +28,9 @@ class QueueSuite extends CatsSuite { checkAll("Queue[Int] with Option", TraverseTests[Queue].traverse[Int, Int, Int, Set[Int], Option, Option]) checkAll("Traverse[Queue]", SerializableTests.serializable(Traverse[Queue])) + checkAll("Queue[Int]", TraverseFilterTests[Queue].traverseFilter[Int, Int, Int]) + checkAll("TraverseFilter[Queue]", SerializableTests.serializable(TraverseFilter[Queue])) + test("show") { Queue(1, 2, 3).show should ===("Queue(1, 2, 3)") Queue.empty[Int].show should ===("Queue()")