From cb321178a58a8a964f499c9b9ab183c6f0399ca1 Mon Sep 17 00:00:00 2001 From: Luka Jacobowitz Date: Fri, 24 Nov 2017 15:13:34 +0100 Subject: [PATCH 1/2] Add &> and <& as syntax for Parallel --- core/src/main/scala/cats/Parallel.scala | 16 ++++++++++++++++ core/src/main/scala/cats/syntax/parallel.scala | 15 ++++++++++++++- .../src/test/scala/cats/tests/SyntaxSuite.scala | 6 ++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/Parallel.scala b/core/src/main/scala/cats/Parallel.scala index 62f2140b67..947a90824f 100644 --- a/core/src/main/scala/cats/Parallel.scala +++ b/core/src/main/scala/cats/Parallel.scala @@ -27,6 +27,22 @@ trait NonEmptyParallel[M[_], F[_]] extends Serializable { */ def parallel: M ~> F + + /** + * Like `Apply[F].followedBy`, but uses the apply instance + * corresponding to the Parallel instance instead. + */ + def parFollowedBy[A, B](ma: M[A])(mb: M[B]): M[B] = + Parallel.parMap2(ma, mb)((_, b) => b)(this) + + + /** + * Like `Apply[F].forEffect`, but uses the apply instance + * corresponding to the Parallel instance instead. + */ + def parForEffect[A, B](ma: M[A])(mb: M[B]): M[A] = + Parallel.parMap2(ma, mb)((a, _) => a)(this) + } /** diff --git a/core/src/main/scala/cats/syntax/parallel.scala b/core/src/main/scala/cats/syntax/parallel.scala index e5bff9bf6c..084d50423c 100644 --- a/core/src/main/scala/cats/syntax/parallel.scala +++ b/core/src/main/scala/cats/syntax/parallel.scala @@ -1,6 +1,6 @@ package cats.syntax -import cats.{Monad, Parallel, Traverse} +import cats.{Monad, Parallel, Traverse, FlatMap} trait ParallelSyntax extends TupleParallelSyntax { implicit final def catsSyntaxParallelTraverse[T[_]: Traverse, A] @@ -8,6 +8,9 @@ trait ParallelSyntax extends TupleParallelSyntax { implicit final def catsSyntaxParallelSequence[T[_]: Traverse, M[_]: Monad, A] (tma: T[M[A]]): ParallelSequenceOps[T, M, A] = new ParallelSequenceOps[T, M, A](tma) + + implicit final def catsSyntaxParallelAp[M[_]: FlatMap, A](ma: M[A]): ParallelApOps[M, A] = + new ParallelApOps[M, A](ma) } @@ -25,3 +28,13 @@ final class ParallelSequenceOps[T[_], M[_], A](val tma: T[M[A]]) extends AnyVal Parallel.parSequence(tma) } + +final class ParallelApOps[M[_], A](val ma: M[A]) extends AnyVal { + + def &>[F[_], B](mb: M[B])(implicit P: Parallel[M, F]): M[B] = + P.parFollowedBy(ma)(mb) + + def <&[F[_], B](mb: M[B])(implicit P: Parallel[M, F]): M[A] = + P.parForEffect(ma)(mb) + +} diff --git a/tests/src/test/scala/cats/tests/SyntaxSuite.scala b/tests/src/test/scala/cats/tests/SyntaxSuite.scala index 736965a2fc..6bcd3b987b 100644 --- a/tests/src/test/scala/cats/tests/SyntaxSuite.scala +++ b/tests/src/test/scala/cats/tests/SyntaxSuite.scala @@ -171,6 +171,12 @@ object SyntaxSuite extends AllInstances with AllSyntax { val tma = mock[T[M[A]]] val mta = tma.parSequence + + val ma = mock[M[A]] + val mb = mock[M[B]] + + val mb2: M[B] = ma &> mb + val ma2: M[A] = ma <& mb } def testParallelTuple[M[_]: Monad, F[_], A, B, C, Z](implicit P: NonEmptyParallel[M, F]) = { From 46cc22ba0d1f7ffa066103d0bd87d26002ebd67a Mon Sep 17 00:00:00 2001 From: Luka Jacobowitz Date: Fri, 24 Nov 2017 16:06:48 +0100 Subject: [PATCH 2/2] Add mima exceptions --- build.sbt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 6a1b4bce06..342b0965ba 100644 --- a/build.sbt +++ b/build.sbt @@ -209,7 +209,10 @@ def mimaSettings(moduleName: String) = Seq( exclude[ReversedMissingMethodProblem]("cats.Foldable.collectFirstSome"), exclude[ReversedMissingMethodProblem]("cats.Foldable.collectFirst"), exclude[ReversedMissingMethodProblem]("cats.Foldable#Ops.collectFirstSome"), - exclude[ReversedMissingMethodProblem]("cats.Foldable#Ops.collectFirst") + exclude[ReversedMissingMethodProblem]("cats.Foldable#Ops.collectFirst"), + exclude[ReversedMissingMethodProblem]("cats.NonEmptyParallel.parForEffect"), + exclude[ReversedMissingMethodProblem]("cats.NonEmptyParallel.parFollowedBy"), + exclude[ReversedMissingMethodProblem]("cats.syntax.ParallelSyntax.catsSyntaxParallelAp") ) } )