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
48 changes: 45 additions & 3 deletions core/src/main/scala/cats/syntax/parallel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,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 @@ -258,8 +269,8 @@ final class ParallelUnorderedFlatSequenceOps[T[_], M[_], A](private val tmta: T[
Parallel.parUnorderedFlatSequence(tmta)
}

@deprecated("Kept for binary compatibility", "2.8.0")
final class ParallelApOps[M[_], A](private val ma: M[A]) extends AnyVal {

def &>[B](mb: M[B])(implicit P: Parallel[M]): M[B] =
P.parProductR(ma)(mb)

Expand All @@ -279,6 +290,29 @@ final class ParallelApOps[M[_], A](private val ma: M[A]) extends AnyVal {
Parallel.parReplicateA(n, ma)
}

final class ParallelApOps1[M[_], A](private val ma: M[A]) extends AnyVal {
def parReplicateA(n: Int)(implicit P: Parallel[M]): M[List[A]] =
Parallel.parReplicateA(n, ma)
}

final class NonEmptyParallelApOps[M[_], A](private val ma: M[A]) extends AnyVal {
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](private val mab: M[A => B]) extends AnyVal {
def <&>(ma: M[A])(implicit P: Parallel[M]): M[B] =
Parallel.parAp(mab)(ma)(P)
Expand All @@ -287,6 +321,14 @@ final class ParallelApplyOps[M[_], A, B](private val mab: M[A => B]) extends Any
Parallel.parAp(mab)(ma)
}

final class NonEmptyParallelApplyOps[M[_], A, B](private 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/shared/src/test/scala/cats/tests/SyntaxSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,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[_]: Parallel, T[_]: Traverse, A, B]: 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 @@ -205,7 +211,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)
val mla: M[List[A]] = ma.parReplicateA(mock[Int])
}

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