diff --git a/kernel/shared/src/main/scala/cats/effect/kernel/syntax/GenConcurrentSyntax.scala b/kernel/shared/src/main/scala/cats/effect/kernel/syntax/GenConcurrentSyntax.scala index a13c925650..b8e3591bd2 100644 --- a/kernel/shared/src/main/scala/cats/effect/kernel/syntax/GenConcurrentSyntax.scala +++ b/kernel/shared/src/main/scala/cats/effect/kernel/syntax/GenConcurrentSyntax.scala @@ -48,11 +48,22 @@ final class GenConcurrentOps_[F[_], A] private[syntax] (private val wrapped: F[A final class ConcurrentParTraverseNOps[T[_], A] private[syntax] ( private val wrapped: T[A] ) extends AnyVal { + + /** + * Like `Parallel.parTraverse`, but limits the degree of parallelism. Note that the semantics + * of this operation aim to maximise fairness: when a spot to execute becomes available, every + * task has a chance to claim it, and not only the next `n` tasks in `ta` + */ def parTraverseN[F[_], B](n: Int)( f: A => F[B] )(implicit T: Traverse[T], F: GenConcurrent[F, _]): F[T[B]] = F.parTraverseN(n)(wrapped)(f) + /** + * Like `Parallel.parTraverse_`, but limits the degree of parallelism. Note that the semantics + * of this operation aim to maximise fairness: when a spot to execute becomes available, every + * task has a chance to claim it, and not only the next `n` tasks in `ta` + */ def parTraverseN_[F[_], B](n: Int)( f: A => F[B] )(implicit T: Foldable[T], F: GenConcurrent[F, _]): F[Unit] = @@ -62,9 +73,16 @@ final class ConcurrentParTraverseNOps[T[_], A] private[syntax] ( final class ConcurrentParSequenceNOps[T[_], F[_], A] private[effect] ( private val wrapped: T[F[A]] ) extends AnyVal { + + /** + * Like `Parallel.parSequence`, but limits the degree of parallelism. + */ def parSequenceN(n: Int)(implicit T: Traverse[T], F: GenConcurrent[F, _]): F[T[A]] = F.parSequenceN(n)(wrapped) + /** + * Like `Parallel.parSequence_`, but limits the degree of parallelism. + */ def parSequenceN_(n: Int)(implicit T: Foldable[T], F: GenConcurrent[F, _]): F[Unit] = F.parSequenceN_(n)(wrapped) }