Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

weaken constraint on ParallelApOps and ParallelApplyOps methods #4078

Merged
merged 11 commits into from
May 25, 2022
52 changes: 47 additions & 5 deletions core/src/main/scala/cats/syntax/parallel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,24 @@ trait ParallelSyntax extends TupleParallelSyntax {
implicit final def catsSyntaxParallelSequence1[T[_]: Traverse, M[_], A](tma: T[M[A]]): ParallelSequenceOps1[T, M, A] =
new ParallelSequenceOps1(tma)

implicit final def catsSyntaxParallelAp[M[_]: FlatMap, A](ma: M[A]): ParallelApOps[M, A] =
@deprecated("Kept for binary compatibility", "2.8.0")
final def catsSyntaxParallelAp[M[_]: FlatMap, A](ma: M[A]): ParallelApOps[M, A] =
new ParallelApOps(ma)

implicit final def catsSyntaxParallelAp1[M[_], A](ma: M[A]): ParallelApOps1[M, A] =
new ParallelApOps1(ma)

implicit final def catsSyntaxNonEmptyParallelAp[M[_], A](ma: M[A]): NonEmptyParallelApOps[M, A] =
new NonEmptyParallelApOps(ma)
}

trait ParallelApplySyntax {
implicit final def catsSyntaxParallelApply[F[_], A, B](fa: F[A => B]): ParallelApplyOps[F, A, B] =
@deprecated("Kept for binary compatibility", "2.8.0")
final def catsSyntaxParallelApply[F[_], A, B](fa: F[A => B]): ParallelApplyOps[F, A, B] =
new ParallelApplyOps(fa)

implicit final def catsSyntaxNonEmptyParallelApply[F[_], A, B](fa: F[A => B]): NonEmptyParallelApplyOps[F, A, B] =
new NonEmptyParallelApplyOps(fa)
}

trait ParallelFlatSyntax {
Expand Down Expand Up @@ -237,8 +248,8 @@ final class ParallelUnorderedFlatSequenceOps[T[_], M[_], A](private val tmta: T[
Parallel.parUnorderedFlatSequence(tmta)
}

final class ParallelApOps[M[_], A](private val ma: M[A]) extends AnyVal {

@deprecated("Kept for binary compatibility", "2.8.0")
final class ParallelApOps[M[_], A](protected val ma: M[A]) extends AnyVal {
def &>[B](mb: M[B])(implicit P: Parallel[M]): M[B] =
P.parProductR(ma)(mb)

Expand All @@ -258,14 +269,45 @@ final class ParallelApOps[M[_], A](private val ma: M[A]) extends AnyVal {
Parallel.parReplicateA(n, ma)
}

final class ParallelApplyOps[M[_], A, B](private val mab: M[A => B]) extends AnyVal {
final class ParallelApOps1[M[_], A](protected val ma: M[A]) extends AnyVal {
def parReplicateA(n: Int)(implicit P: Parallel[M]): M[List[A]] =
Parallel.parReplicateA(n, ma)
}
satorg marked this conversation as resolved.
Show resolved Hide resolved

final class NonEmptyParallelApOps[M[_], A](protected val ma: M[A]) extends AnyVal {
satorg marked this conversation as resolved.
Show resolved Hide resolved
def &>[B](mb: M[B])(implicit P: NonEmptyParallel[M]): M[B] =
P.parProductR[A, B](ma)(mb)

def <&[B](mb: M[B])(implicit P: NonEmptyParallel[M]): M[A] =
P.parProductL[A, B](ma)(mb)

def parProductL[B](mb: M[B])(implicit P: NonEmptyParallel[M]): M[A] =
P.parProductL[A, B](ma)(mb)

def parProductR[B](mb: M[B])(implicit P: NonEmptyParallel[M]): M[B] =
P.parProductR[A, B](ma)(mb)

def parProduct[B](mb: M[B])(implicit P: NonEmptyParallel[M]): M[(A, B)] =
Parallel.parProduct(ma, mb)
}

@deprecated("Kept for binary compatibility", "2.8.0")
final class ParallelApplyOps[M[_], A, B](protected val mab: M[A => B]) extends AnyVal {
def <&>(ma: M[A])(implicit P: Parallel[M]): M[B] =
Parallel.parAp(mab)(ma)(P)

def parAp(ma: M[A])(implicit P: Parallel[M]): M[B] =
Parallel.parAp(mab)(ma)
}

final class NonEmptyParallelApplyOps[M[_], A, B](protected val mab: M[A => B]) extends AnyVal {
def <&>(ma: M[A])(implicit P: NonEmptyParallel[M]): M[B] =
Parallel.parAp[M, A, B](mab)(ma)(P)

def parAp(ma: M[A])(implicit P: NonEmptyParallel[M]): M[B] =
Parallel.parAp[M, A, B](mab)(ma)
}

final class ParallelBitraverseOps[T[_, _], A, B](private val tab: T[A, B]) extends AnyVal {
def parBitraverse[M[_], C, D](f: A => M[C], g: B => M[D])(implicit T: Bitraverse[T], P: Parallel[M]): M[T[C, D]] =
Parallel.parBitraverse(tab)(f, g)
Expand Down
9 changes: 7 additions & 2 deletions tests/src/test/scala/cats/tests/SyntaxSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,20 @@ object SyntaxSuite {
val gunit: G[F[A]] = fga.nonEmptySequence
}

def testParallel[M[_]: Monad, F[_], T[_]: Traverse, A, B](implicit P: Parallel.Aux[M, F]): Unit = {
def testParallel[M[_], F[_], T[_]: Traverse, A, B](implicit P: Parallel.Aux[M, F]): Unit = {
val ta = mock[T[A]]
val f = mock[A => M[B]]
val mtb = ta.parTraverse(f)

val tma = mock[T[M[A]]]
val mta = tma.parSequence

val ma = mock[M[A]]

val mla: M[List[A]] = ma.parReplicateA(mock[Int])
}

def testNonEmptyParallel[M[_]: NonEmptyParallel, A, B]: Unit = {
val ma = mock[M[A]]
val mb = mock[M[B]]

Expand All @@ -184,7 +190,6 @@ object SyntaxSuite {
val mb4: M[B] = ma.parProductR(mb)
val mab2: M[(A, B)] = ma.parProduct(mb)
val mb5: M[B] = mab.parAp(ma)
satorg marked this conversation as resolved.
Show resolved Hide resolved
val mla: M[List[A]] = ma.parReplicateA(mock[Int])
}

def testParallelUnorderedTraverse[M[_]: Monad, F[_]: CommutativeApplicative, T[_]: UnorderedTraverse: FlatMap, A, B](
Expand Down