Skip to content

Commit f82cd0d

Browse files
backported #3103 Add traverseFilter instances for Queue (#3292)
1 parent 0980189 commit f82cd0d

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

core/src/main/scala/cats/instances/all.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,6 @@ trait AllInstancesBinCompat7
6969
with VectorInstancesBinCompat1
7070
with EitherInstancesBinCompat0
7171
with StreamInstancesBinCompat1
72+
with QueueInstancesBinCompat0
7273
with TailRecInstances
7374
with SortedSetInstancesBinCompat2

core/src/main/scala/cats/instances/queue.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cats
22
package instances
33

44
import cats.syntax.show._
5+
56
import scala.annotation.tailrec
67
import scala.collection.immutable.Queue
78
import scala.util.Try
@@ -153,3 +154,31 @@ trait QueueInstances extends cats.kernel.instances.QueueInstances {
153154
fa.iterator.map(_.show).mkString("Queue(", ", ", ")")
154155
}
155156
}
157+
158+
private[instances] trait QueueInstancesBinCompat0 {
159+
implicit val catsStdTraverseFilterForQueue: TraverseFilter[Queue] = new TraverseFilter[Queue] {
160+
val traverse: Traverse[Queue] = cats.instances.queue.catsStdInstancesForQueue
161+
162+
override def mapFilter[A, B](fa: Queue[A])(f: (A) => Option[B]): Queue[B] =
163+
fa.collect(Function.unlift(f))
164+
165+
override def filter[A](fa: Queue[A])(f: (A) => Boolean): Queue[A] = fa.filter(f)
166+
167+
override def collect[A, B](fa: Queue[A])(f: PartialFunction[A, B]): Queue[B] = fa.collect(f)
168+
169+
override def flattenOption[A](fa: Queue[Option[A]]): Queue[A] = fa.flatten
170+
171+
def traverseFilter[G[_], A, B](fa: Queue[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Queue[B]] =
172+
fa.foldRight(Eval.now(G.pure(Queue.empty[B])))(
173+
(x, xse) => G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ +: o))
174+
)
175+
.value
176+
177+
override def filterA[G[_], A](fa: Queue[A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[Queue[A]] =
178+
fa.foldRight(Eval.now(G.pure(Queue.empty[A])))(
179+
(x, xse) => G.map2Eval(f(x), xse)((b, vec) => if (b) x +: vec else vec)
180+
)
181+
.value
182+
}
183+
184+
}

tests/src/test/scala/cats/tests/QueueSuite.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ package cats
22
package tests
33

44
import scala.collection.immutable.Queue
5-
65
import cats.laws.discipline.{
76
AlternativeTests,
87
CoflatMapTests,
98
MonadTests,
109
SemigroupalTests,
1110
SerializableTests,
11+
TraverseFilterTests,
1212
TraverseTests
1313
}
1414

@@ -28,6 +28,9 @@ class QueueSuite extends CatsSuite {
2828
checkAll("Queue[Int] with Option", TraverseTests[Queue].traverse[Int, Int, Int, Set[Int], Option, Option])
2929
checkAll("Traverse[Queue]", SerializableTests.serializable(Traverse[Queue]))
3030

31+
checkAll("Queue[Int]", TraverseFilterTests[Queue].traverseFilter[Int, Int, Int])
32+
checkAll("TraverseFilter[Queue]", SerializableTests.serializable(TraverseFilter[Queue]))
33+
3134
test("show") {
3235
Queue(1, 2, 3).show should ===("Queue(1, 2, 3)")
3336
Queue.empty[Int].show should ===("Queue()")

0 commit comments

Comments
 (0)