diff --git a/core/src/main/scala-2.12/cats/instances/all.scala b/core/src/main/scala-2.12/cats/instances/all.scala index 001e20ccf0e..0212a6bff0c 100644 --- a/core/src/main/scala-2.12/cats/instances/all.scala +++ b/core/src/main/scala-2.12/cats/instances/all.scala @@ -10,6 +10,7 @@ abstract class AllInstancesBinCompat with AllInstancesBinCompat4 with AllInstancesBinCompat5 with AllInstancesBinCompat6 + with AllInstancesBinCompat7 trait AllInstances extends AnyValInstances @@ -62,3 +63,5 @@ trait AllInstancesBinCompat4 extends SortedMapInstancesBinCompat1 with MapInstan trait AllInstancesBinCompat5 extends SortedSetInstancesBinCompat0 trait AllInstancesBinCompat6 extends SortedSetInstancesBinCompat1 with SortedMapInstancesBinCompat2 + +trait AllInstancesBinCompat7 extends QueueInstancesBinCompat0 diff --git a/core/src/main/scala-2.12/cats/instances/package.scala b/core/src/main/scala-2.12/cats/instances/package.scala index d905f919e7b..cbae6f4a2b3 100644 --- a/core/src/main/scala-2.12/cats/instances/package.scala +++ b/core/src/main/scala-2.12/cats/instances/package.scala @@ -28,7 +28,7 @@ package object instances { object parallel extends ParallelInstances object partialOrder extends PartialOrderInstances object partialOrdering extends PartialOrderingInstances - object queue extends QueueInstances + object queue extends QueueInstances with QueueInstancesBinCompat0 object set extends SetInstances object short extends ShortInstances object sortedMap diff --git a/core/src/main/scala-2.13+/cats/instances/all.scala b/core/src/main/scala-2.13+/cats/instances/all.scala index 315b99eefdf..65b9a32ecfd 100644 --- a/core/src/main/scala-2.13+/cats/instances/all.scala +++ b/core/src/main/scala-2.13+/cats/instances/all.scala @@ -10,6 +10,7 @@ abstract class AllInstancesBinCompat with AllInstancesBinCompat4 with AllInstancesBinCompat5 with AllInstancesBinCompat6 + with AllInstancesBinCompat7 trait AllInstances extends AnyValInstances @@ -63,3 +64,5 @@ trait AllInstancesBinCompat4 extends SortedMapInstancesBinCompat1 with MapInstan trait AllInstancesBinCompat5 extends SortedSetInstancesBinCompat0 trait AllInstancesBinCompat6 extends SortedSetInstancesBinCompat1 with SortedMapInstancesBinCompat2 + +trait AllInstancesBinCompat7 extends QueueInstancesBinCompat0 diff --git a/core/src/main/scala-2.13+/cats/instances/package.scala b/core/src/main/scala-2.13+/cats/instances/package.scala index 6081280fb58..e3c90b00e9f 100644 --- a/core/src/main/scala-2.13+/cats/instances/package.scala +++ b/core/src/main/scala-2.13+/cats/instances/package.scala @@ -28,7 +28,7 @@ package object instances { object parallel extends ParallelInstances object partialOrder extends PartialOrderInstances object partialOrdering extends PartialOrderingInstances - object queue extends QueueInstances + object queue extends QueueInstances with QueueInstancesBinCompat0 object set extends SetInstances object short extends ShortInstances object sortedMap diff --git a/core/src/main/scala/cats/instances/queue.scala b/core/src/main/scala/cats/instances/queue.scala index aebedd10de2..289ab83d9f3 100644 --- a/core/src/main/scala/cats/instances/queue.scala +++ b/core/src/main/scala/cats/instances/queue.scala @@ -153,3 +153,30 @@ 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/CatsSuite.scala b/tests/src/test/scala/cats/tests/CatsSuite.scala index ff691f95b8f..ac44f171ad8 100644 --- a/tests/src/test/scala/cats/tests/CatsSuite.scala +++ b/tests/src/test/scala/cats/tests/CatsSuite.scala @@ -45,6 +45,7 @@ trait CatsSuite with AllInstancesBinCompat4 with AllInstancesBinCompat5 with AllInstancesBinCompat6 + with AllInstancesBinCompat7 with AllSyntax with AllSyntaxBinCompat0 with AllSyntaxBinCompat1 diff --git a/tests/src/test/scala/cats/tests/QueueSuite.scala b/tests/src/test/scala/cats/tests/QueueSuite.scala index a6320224658..255adc0f6fb 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()")