Skip to content

Commit bfda65b

Browse files
authored
Merge pull request #4682 from satorg/name-to-nameVoid
Aliases `traverseVoid`/`sequenceVoid` and their counterparts
2 parents 9aed5c4 + e8d95ee commit bfda65b

File tree

23 files changed

+202
-92
lines changed

23 files changed

+202
-92
lines changed

bench/src/main/scala/cats/bench/TraverseBench.scala

+9-6
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ class TraverseBench {
8989
}
9090
}
9191

92+
// TODO: consider renaming to `traverseVoidList`
9293
@Benchmark
93-
def traverse_List(bh: Blackhole) = {
94-
val result = listT.traverse_(list) { i =>
94+
def traverse_List(bh: Blackhole): Unit = {
95+
val result = listT.traverseVoid(list) { i =>
9596
Eval.later {
9697
Blackhole.consumeCPU(Work)
9798
i * 2
@@ -155,9 +156,10 @@ class TraverseBench {
155156
bh.consume(result.value)
156157
}
157158

159+
// TODO: consider renaming to `traverseVoidVector`
158160
@Benchmark
159-
def traverse_Vector(bh: Blackhole) = {
160-
val result = vectorT.traverse_(vector) { i =>
161+
def traverse_Vector(bh: Blackhole): Unit = {
162+
val result = vectorT.traverseVoid(vector) { i =>
161163
Eval.later {
162164
Blackhole.consumeCPU(Work)
163165
i * 2
@@ -242,9 +244,10 @@ class TraverseBench {
242244
bh.consume(result.value)
243245
}
244246

247+
// TODO: consider renaming to `traverseVoidChain`
245248
@Benchmark
246-
def traverse_Chain(bh: Blackhole) = {
247-
val result = chainT.traverse_(chain) { i =>
249+
def traverse_Chain(bh: Blackhole): Unit = {
250+
val result = chainT.traverseVoid(chain) { i =>
248251
Eval.later {
249252
Blackhole.consumeCPU(Work)
250253
i * 2

core/src/main/scala-2.13+/cats/instances/arraySeq.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ private[cats] object ArraySeqInstances {
110110

111111
}
112112

113-
override def traverse_[G[_], A, B](fa: ArraySeq[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
113+
override def traverseVoid[G[_], A, B](fa: ArraySeq[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
114114
G match {
115-
case x: StackSafeMonad[G] => Traverse.traverse_Directly(fa)(f)(x)
115+
case x: StackSafeMonad[G] => Traverse.traverseVoidDirectly(fa)(f)(x)
116116
case _ =>
117117
foldRight(fa, Eval.now(G.unit)) { (a, acc) =>
118118
G.map2Eval(f(a), acc) { (_, _) =>

core/src/main/scala/cats/Foldable.scala

+32-9
Original file line numberDiff line numberDiff line change
@@ -578,42 +578,58 @@ trait Foldable[F[_]] extends UnorderedFoldable[F] with FoldableNFunctions[F] { s
578578
* scala> import cats.syntax.all._
579579
* scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption
580580
* scala> val F = Foldable[List]
581-
* scala> F.traverse_(List("333", "444"))(parseInt)
581+
* scala> F.traverseVoid(List("333", "444"))(parseInt)
582582
* res0: Option[Unit] = Some(())
583-
* scala> F.traverse_(List("333", "zzz"))(parseInt)
583+
* scala> F.traverseVoid(List("333", "zzz"))(parseInt)
584584
* res1: Option[Unit] = None
585585
* }}}
586586
*
587587
* This method is primarily useful when `G[_]` represents an action
588588
* or effect, and the specific `A` aspect of `G[A]` is not otherwise
589589
* needed.
590590
*/
591-
def traverse_[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
591+
def traverseVoid[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
592592
foldRight(fa, Always(G.unit)) { (a, acc) =>
593593
G.map2Eval(f(a), acc) { (_, _) =>
594594
()
595595
}
596596
}.value
597597

598+
/**
599+
* Alias for `traverseVoid`.
600+
*
601+
* @deprecated this method should be considered as deprecated and replaced by `traverseVoid`.
602+
*/
603+
def traverse_[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
604+
traverseVoid(fa)(f)
605+
598606
/**
599607
* Sequence `F[G[A]]` using `Applicative[G]`.
600608
*
601-
* This is similar to `traverse_` except it operates on `F[G[A]]`
609+
* This is similar to `traverseVoid` except it operates on `F[G[A]]`
602610
* values, so no additional functions are needed.
603611
*
604612
* For example:
605613
*
606614
* {{{
607615
* scala> import cats.syntax.all._
608616
* scala> val F = Foldable[List]
609-
* scala> F.sequence_(List(Option(1), Option(2), Option(3)))
617+
* scala> F.sequenceVoid(List(Option(1), Option(2), Option(3)))
610618
* res0: Option[Unit] = Some(())
611-
* scala> F.sequence_(List(Option(1), None, Option(3)))
619+
* scala> F.sequenceVoid(List(Option(1), None, Option(3)))
612620
* res1: Option[Unit] = None
613621
* }}}
614622
*/
623+
def sequenceVoid[G[_]: Applicative, A](fga: F[G[A]]): G[Unit] =
624+
traverseVoid(fga)(identity)
625+
626+
/**
627+
* Alias for `sequenceVoid`.
628+
*
629+
* @deprecated this method should be considered as deprecated and replaced by `sequenceVoid`.
630+
*/
615631
def sequence_[G[_]: Applicative, A](fga: F[G[A]]): G[Unit] =
616-
traverse_(fga)(identity)
632+
sequenceVoid(fga)
617633

618634
/**
619635
* Fold implemented using the given `MonoidK[G]` instance.
@@ -1053,10 +1069,17 @@ object Foldable {
10531069
typeClassInstance.foldMapM[G, A, B](self)(f)(G, B)
10541070
def foldMapA[G[_], B](f: A => G[B])(implicit G: Applicative[G], B: Monoid[B]): G[B] =
10551071
typeClassInstance.foldMapA[G, A, B](self)(f)(G, B)
1072+
def traverseVoid[G[_], B](f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
1073+
typeClassInstance.traverseVoid[G, A, B](self)(f)(G)
10561074
def traverse_[G[_], B](f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
1057-
typeClassInstance.traverse_[G, A, B](self)(f)(G)
1075+
traverseVoid[G, B](f)
1076+
// TODO: looks like these two methods below duplicate the same named methods from `NestedFoldableOps`.
1077+
// Moreover, the other two methods take precedence, thereby these two are not in use whatsoever.
1078+
// Perhaps it makes sense to deprecate one pair of them either here or there.
1079+
def sequenceVoid[G[_], B](implicit ev$1: A <:< G[B], ev$2: Applicative[G]): G[Unit] =
1080+
typeClassInstance.sequenceVoid[G, B](self.asInstanceOf[F[G[B]]])
10581081
def sequence_[G[_], B](implicit ev$1: A <:< G[B], ev$2: Applicative[G]): G[Unit] =
1059-
typeClassInstance.sequence_[G, B](self.asInstanceOf[F[G[B]]])
1082+
sequenceVoid[G, B]
10601083
def foldK[G[_], B](implicit ev$1: A <:< G[B], G: MonoidK[G]): G[B] =
10611084
typeClassInstance.foldK[G, B](self.asInstanceOf[F[G[B]]])(G)
10621085
def find(f: A => Boolean): Option[A] = typeClassInstance.find[A](self)(f)

core/src/main/scala/cats/Parallel.scala

+48-14
Original file line numberDiff line numberDiff line change
@@ -260,25 +260,39 @@ object Parallel extends ParallelArityFunctions2 {
260260
}
261261

262262
/**
263-
* Like `Foldable[A].sequence_`, but uses the applicative instance
263+
* Like `Foldable[A].sequenceVoid`, but uses the applicative instance
264264
* corresponding to the Parallel instance instead.
265265
*/
266-
def parSequence_[T[_]: Foldable, M[_], A](tma: T[M[A]])(implicit P: Parallel[M]): M[Unit] = {
267-
val fu: P.F[Unit] = Foldable[T].traverse_(tma)(P.parallel.apply(_))(P.applicative)
266+
def parSequenceVoid[T[_]: Foldable, M[_], A](tma: T[M[A]])(implicit P: Parallel[M]): M[Unit] = {
267+
val fu: P.F[Unit] = Foldable[T].traverseVoid(tma)(P.parallel.apply(_))(P.applicative)
268268
P.sequential(fu)
269269
}
270270

271271
/**
272-
* Like `Foldable[A].traverse_`, but uses the applicative instance
272+
* Alias for `parSequenceVoid`.
273+
*
274+
* @deprecated this method should be considered as deprecated and replaced by `parSequenceVoid`.
275+
*/
276+
def parSequence_[T[_]: Foldable, M[_], A](tma: T[M[A]])(implicit P: Parallel[M]): M[Unit] =
277+
parSequenceVoid(tma)
278+
279+
/**
280+
* Like `Foldable[A].traverseVoid`, but uses the applicative instance
273281
* corresponding to the Parallel instance instead.
274282
*/
275-
def parTraverse_[T[_]: Foldable, M[_], A, B](
276-
ta: T[A]
277-
)(f: A => M[B])(implicit P: Parallel[M]): M[Unit] = {
278-
val gtb: P.F[Unit] = Foldable[T].traverse_(ta)(a => P.parallel(f(a)))(P.applicative)
283+
def parTraverseVoid[T[_]: Foldable, M[_], A, B](ta: T[A])(f: A => M[B])(implicit P: Parallel[M]): M[Unit] = {
284+
val gtb: P.F[Unit] = Foldable[T].traverseVoid(ta)(a => P.parallel(f(a)))(P.applicative)
279285
P.sequential(gtb)
280286
}
281287

288+
/**
289+
* Alias for `parTraverseVoid`.
290+
*
291+
* @deprecated this method should be considered as deprecated and replaced by `parTraverseVoid`.
292+
*/
293+
def parTraverse_[T[_]: Foldable, M[_], A, B](ta: T[A])(f: A => M[B])(implicit P: Parallel[M]): M[Unit] =
294+
parTraverseVoid(ta)(f)
295+
282296
def parUnorderedTraverse[T[_]: UnorderedTraverse, M[_], F[_]: CommutativeApplicative, A, B](
283297
ta: T[A]
284298
)(f: A => M[B])(implicit P: Parallel.Aux[M, F]): M[T[B]] =
@@ -345,27 +359,47 @@ object Parallel extends ParallelArityFunctions2 {
345359
}
346360

347361
/**
348-
* Like `Reducible[A].nonEmptySequence_`, but uses the apply instance
362+
* Like `Reducible[A].nonEmptySequenceVoid`, but uses the apply instance
349363
* corresponding to the Parallel instance instead.
350364
*/
351-
def parNonEmptySequence_[T[_]: Reducible, M[_], A](
365+
def parNonEmptySequenceVoid[T[_]: Reducible, M[_], A](
352366
tma: T[M[A]]
353367
)(implicit P: NonEmptyParallel[M]): M[Unit] = {
354-
val fu: P.F[Unit] = Reducible[T].nonEmptyTraverse_(tma)(P.parallel.apply(_))(P.apply)
368+
val fu: P.F[Unit] = Reducible[T].nonEmptyTraverseVoid(tma)(P.parallel.apply(_))(P.apply)
355369
P.sequential(fu)
356370
}
357371

358372
/**
359-
* Like `Reducible[A].nonEmptyTraverse_`, but uses the apply instance
373+
* Alias for `parNonEmptySequenceVoid`.
374+
*
375+
* @deprecated this method should be considered as deprecated and replaced by `parNonEmptySequenceVoid`.
376+
*/
377+
def parNonEmptySequence_[T[_]: Reducible, M[_], A](
378+
tma: T[M[A]]
379+
)(implicit P: NonEmptyParallel[M]): M[Unit] =
380+
parNonEmptySequenceVoid[T, M, A](tma)
381+
382+
/**
383+
* Like `Reducible[A].nonEmptyTraverseVoid`, but uses the apply instance
360384
* corresponding to the Parallel instance instead.
361385
*/
362-
def parNonEmptyTraverse_[T[_]: Reducible, M[_], A, B](
386+
def parNonEmptyTraverseVoid[T[_]: Reducible, M[_], A, B](
363387
ta: T[A]
364388
)(f: A => M[B])(implicit P: NonEmptyParallel[M]): M[Unit] = {
365-
val gtb: P.F[Unit] = Reducible[T].nonEmptyTraverse_(ta)(a => P.parallel(f(a)))(P.apply)
389+
val gtb: P.F[Unit] = Reducible[T].nonEmptyTraverseVoid(ta)(a => P.parallel(f(a)))(P.apply)
366390
P.sequential(gtb)
367391
}
368392

393+
/**
394+
* Alias for `parNonEmptyTraverseVoid`.
395+
*
396+
* @deprecated this method should be considered as deprecated and replaced by `parNonEmptyTraverseVoid`.
397+
*/
398+
def parNonEmptyTraverse_[T[_]: Reducible, M[_], A, B](
399+
ta: T[A]
400+
)(f: A => M[B])(implicit P: NonEmptyParallel[M]): M[Unit] =
401+
parNonEmptyTraverseVoid[T, M, A, B](ta)(f)
402+
369403
/**
370404
* Like `Bitraverse[A].bitraverse`, but uses the applicative instance
371405
* corresponding to the Parallel instance instead.

core/src/main/scala/cats/Reducible.scala

+28-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
package cats
2323

24-
import cats.Foldable.Source
2524
import cats.data.{Ior, NonEmptyList}
2625

2726
/**
@@ -202,31 +201,47 @@ trait Reducible[F[_]] extends Foldable[F] { self =>
202201
* `A` values will be mapped into `G[B]` and combined using
203202
* `Apply#map2`.
204203
*
205-
* This method is similar to [[Foldable.traverse_]]. There are two
204+
* This method is similar to [[Foldable.traverseVoid]]. There are two
206205
* main differences:
207206
*
208207
* 1. We only need an [[Apply]] instance for `G` here, since we
209208
* don't need to call [[Applicative.pure]] for a starting value.
210209
* 2. This performs a strict left-associative traversal and thus
211210
* must always traverse the entire data structure. Prefer
212-
* [[Foldable.traverse_]] if you have an [[Applicative]] instance
211+
* [[Foldable.traverseVoid]] if you have an [[Applicative]] instance
213212
* available for `G` and want to take advantage of short-circuiting
214213
* the traversal.
215214
*/
216-
def nonEmptyTraverse_[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Apply[G]): G[Unit] = {
215+
def nonEmptyTraverseVoid[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Apply[G]): G[Unit] = {
217216
val f1 = f.andThen(G.void)
218217
reduceRightTo(fa)(f1)((x, y) => G.map2Eval(f1(x), y)((_, b) => b)).value
219218
}
220219

220+
/**
221+
* Alias for `nonEmptyTraverseVoid`.
222+
*
223+
* @deprecated this method should be considered as deprecated and replaced by `nonEmptyTraverseVoid`.
224+
*/
225+
def nonEmptyTraverse_[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Apply[G]): G[Unit] =
226+
nonEmptyTraverseVoid(fa)(f)
227+
221228
/**
222229
* Sequence `F[G[A]]` using `Apply[G]`.
223230
*
224-
* This method is similar to [[Foldable.sequence_]] but requires only
231+
* This method is similar to [[Foldable.sequenceVoid]] but requires only
225232
* an [[Apply]] instance for `G` instead of [[Applicative]]. See the
226-
* [[nonEmptyTraverse_]] documentation for a description of the differences.
233+
* [[nonEmptyTraverseVoid]] documentation for a description of the differences.
234+
*/
235+
def nonEmptySequenceVoid[G[_], A](fga: F[G[A]])(implicit G: Apply[G]): G[Unit] =
236+
nonEmptyTraverseVoid(fga)(identity)
237+
238+
/**
239+
* Alias for `nonEmptySequenceVoid`.
240+
*
241+
* @deprecated this method should be considered as deprecated and replaced by `nonEmptySequenceVoid`.
227242
*/
228243
def nonEmptySequence_[G[_], A](fga: F[G[A]])(implicit G: Apply[G]): G[Unit] =
229-
nonEmptyTraverse_(fga)(identity)
244+
nonEmptySequenceVoid(fga)
230245

231246
def toNonEmptyList[A](fa: F[A]): NonEmptyList[A] =
232247
reduceRightTo(fa)(a => NonEmptyList(a, Nil)) { (a, lnel) =>
@@ -399,10 +414,14 @@ object Reducible {
399414
typeClassInstance.reduceMapM[G, A, B](self)(f)(G, B)
400415
def reduceRightTo[B](f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] =
401416
typeClassInstance.reduceRightTo[A, B](self)(f)(g)
417+
def nonEmptyTraverseVoid[G[_], B](f: A => G[B])(implicit G: Apply[G]): G[Unit] =
418+
typeClassInstance.nonEmptyTraverseVoid[G, A, B](self)(f)
402419
def nonEmptyTraverse_[G[_], B](f: A => G[B])(implicit G: Apply[G]): G[Unit] =
403-
typeClassInstance.nonEmptyTraverse_[G, A, B](self)(f)(G)
420+
nonEmptyTraverseVoid[G, B](f)
421+
def nonEmptySequenceVoid[G[_], B](implicit ev$1: A <:< G[B], G: Apply[G]): G[Unit] =
422+
typeClassInstance.nonEmptySequenceVoid[G, B](self.asInstanceOf[F[G[B]]])
404423
def nonEmptySequence_[G[_], B](implicit ev$1: A <:< G[B], G: Apply[G]): G[Unit] =
405-
typeClassInstance.nonEmptySequence_[G, B](self.asInstanceOf[F[G[B]]])(G)
424+
nonEmptySequenceVoid[G, B]
406425
def toNonEmptyList: NonEmptyList[A] = typeClassInstance.toNonEmptyList[A](self)
407426
def minimum(implicit A: Order[A]): A = typeClassInstance.minimum[A](self)(A)
408427
def maximum(implicit A: Order[A]): A = typeClassInstance.maximum[A](self)(A)

core/src/main/scala/cats/Traverse.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ object Traverse {
296296
}
297297
}
298298

299-
private[cats] def traverse_Directly[G[_], A, B](
299+
private[cats] def traverseVoidDirectly[G[_], A, B](
300300
fa: IterableOnce[A]
301301
)(f: A => G[B])(implicit G: StackSafeMonad[G]): G[Unit] = {
302302
val iter = fa.iterator

core/src/main/scala/cats/data/Chain.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -1254,9 +1254,9 @@ sealed abstract private[data] class ChainInstances extends ChainInstances1 {
12541254
}(f)
12551255
}
12561256

1257-
override def traverse_[G[_], A, B](fa: Chain[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
1257+
override def traverseVoid[G[_], A, B](fa: Chain[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
12581258
G match {
1259-
case x: StackSafeMonad[G] => Traverse.traverse_Directly(fa.iterator)(f)(x)
1259+
case x: StackSafeMonad[G] => Traverse.traverseVoidDirectly(fa.iterator)(f)(x)
12601260
case _ =>
12611261
foldRight(fa, Eval.now(G.unit)) { (a, acc) =>
12621262
G.map2Eval(f(a), acc) { (_, _) =>

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ trait ListInstances extends cats.kernel.instances.ListInstances {
134134
/**
135135
* This avoids making a very deep stack by building a tree instead
136136
*/
137-
override def traverse_[G[_], A, B](fa: List[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] = {
137+
override def traverseVoid[G[_], A, B](fa: List[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] = {
138138
G match {
139-
case x: StackSafeMonad[G] => Traverse.traverse_Directly(fa)(f)(x)
139+
case x: StackSafeMonad[G] => Traverse.traverseVoidDirectly(fa)(f)(x)
140140
case _ =>
141141
// the cost of this is O(size log size)
142142
// c(n) = n + 2 * c(n/2) = n + 2(n/2 log (n/2)) = n + n (logn - 1) = n log n

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ trait QueueInstances extends cats.kernel.instances.QueueInstances {
133133
}
134134
}
135135

136-
override def traverse_[G[_], A, B](fa: Queue[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
136+
override def traverseVoid[G[_], A, B](fa: Queue[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
137137
G match {
138-
case x: StackSafeMonad[G] => Traverse.traverse_Directly(fa)(f)(x)
138+
case x: StackSafeMonad[G] => Traverse.traverseVoidDirectly(fa)(f)(x)
139139
case _ =>
140140
foldRight(fa, Eval.now(G.unit)) { (a, acc) =>
141141
G.map2Eval(f(a), acc) { (_, _) =>

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ trait SeqInstances extends cats.kernel.instances.SeqInstances {
133133
G.map(Chain.traverseViaChain(fa.toIndexedSeq)(f))(_.toList)
134134
}
135135

136-
override def traverse_[G[_], A, B](fa: Seq[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
136+
override def traverseVoid[G[_], A, B](fa: Seq[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] =
137137
G match {
138-
case x: StackSafeMonad[G] => Traverse.traverse_Directly(fa)(f)(x)
138+
case x: StackSafeMonad[G] => Traverse.traverseVoidDirectly(fa)(f)(x)
139139
case _ =>
140140
foldRight(fa, Eval.now(G.unit)) { (a, acc) =>
141141
G.map2Eval(f(a), acc) { (_, _) =>

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ trait VectorInstances extends cats.kernel.instances.VectorInstances {
140140
/**
141141
* This avoids making a very deep stack by building a tree instead
142142
*/
143-
override def traverse_[G[_], A, B](fa: Vector[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] = {
143+
override def traverseVoid[G[_], A, B](fa: Vector[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] = {
144144
G match {
145-
case x: StackSafeMonad[G] => Traverse.traverse_Directly(fa)(f)(x)
145+
case x: StackSafeMonad[G] => Traverse.traverseVoidDirectly(fa)(f)(x)
146146
case _ =>
147147
// the cost of this is O(size)
148148
// c(n) = 1 + 2 * c(n/2)

0 commit comments

Comments
 (0)