Skip to content

Commit

Permalink
Merge pull request #3147 from nigredo-tori/parfoldmapa
Browse files Browse the repository at this point in the history
Add Parallel.parFoldMapA
  • Loading branch information
travisbrown authored Nov 14, 2019
2 parents 53a0f59 + 0259244 commit bd82ff2
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 1 deletion.
12 changes: 12 additions & 0 deletions core/src/main/scala/cats/Parallel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,18 @@ object Parallel extends ParallelArityFunctions2 {
P.sequential(ftab)
}

/**
* Like `Foldable[A].foldMapA`, but uses the applicative instance
* corresponding to the Parallel instance instead.
*/
def parFoldMapA[T[_], M[_], A, B](
ta: T[A]
)(f: A => M[B])(implicit T: Foldable[T], P: Parallel[M], B: Monoid[B]): M[B] = {
val fb: P.F[B] =
Foldable[T].foldMapA(ta)(a => P.parallel(f(a)))(P.applicative, B)
P.sequential(fb)
}

/**
* Like `Applicative[F].ap`, but uses the applicative instance
* corresponding to the Parallel instance instead.
Expand Down
1 change: 1 addition & 0 deletions core/src/main/scala/cats/syntax/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ trait AllSyntax
with ValidatedSyntax
with VectorSyntax
with WriterSyntax
with ParallelFoldMapASyntax

trait AllSyntaxBinCompat0 extends UnorderedTraverseSyntax with ApplicativeErrorExtension with TrySyntax

Expand Down
1 change: 1 addition & 0 deletions core/src/main/scala/cats/syntax/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ package object syntax {
with ParallelApplySyntax
with ParallelBitraverseSyntax
with ParallelUnorderedTraverseSyntax
with ParallelFoldMapASyntax
object partialOrder extends PartialOrderSyntax
object profunctor extends ProfunctorSyntax
object reducible extends ReducibleSyntax with ReducibleSyntaxBinCompat0
Expand Down
22 changes: 21 additions & 1 deletion core/src/main/scala/cats/syntax/parallel.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
package cats.syntax

import cats.{Bitraverse, CommutativeApplicative, FlatMap, Foldable, Monad, Parallel, Traverse, UnorderedTraverse}
import cats.{
Bitraverse,
CommutativeApplicative,
FlatMap,
Foldable,
Monad,
Monoid,
Parallel,
Traverse,
UnorderedTraverse
}

trait ParallelSyntax extends TupleParallelSyntax {

Expand Down Expand Up @@ -79,6 +89,11 @@ trait ParallelUnorderedTraverseSyntax {

}

trait ParallelFoldMapASyntax {
implicit final def catsSyntaxParallelFoldMapA[T[_], A](ta: T[A]): ParallelFoldMapAOps[T, A] =
new ParallelFoldMapAOps[T, A](ta)
}

final class ParallelTraversableOps[T[_], A](private val ta: T[A]) extends AnyVal {
def parTraverse[M[_]: Monad, B](f: A => M[B])(implicit T: Traverse[T], P: Parallel[M]): M[T[B]] =
Parallel.parTraverse(ta)(f)
Expand Down Expand Up @@ -176,3 +191,8 @@ final class ParallelLeftSequenceOps[T[_, _], M[_], A, B](private val tmab: T[M[A
def parLeftSequence(implicit T: Bitraverse[T], P: Parallel[M]): M[T[A, B]] =
Parallel.parLeftSequence(tmab)
}

final class ParallelFoldMapAOps[T[_], A](private val ma: T[A]) extends AnyVal {
def parFoldMapA[M[_], B](f: A => M[B])(implicit T: Foldable[T], P: Parallel[M], B: Monoid[B]): M[B] =
Parallel.parFoldMapA(ma)(f)
}
8 changes: 8 additions & 0 deletions tests/src/test/scala/cats/tests/ParallelSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,14 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest with Sc
}
}

test("ParFoldMapA should be equivalent to parTraverse map combineAll (where it exists)") {
forAll { (es: List[Int], f: Int => Either[String, String]) =>
Parallel.parFoldMapA(es)(f) should ===(
Parallel.parTraverse(es)(f).map(_.combineAll)
)
}
}

test("parAp accumulates errors in order") {
val right: Either[String, Int => Int] = Left("Hello")
Parallel.parAp(right)("World".asLeft) should ===(Left("HelloWorld"))
Expand Down
6 changes: 6 additions & 0 deletions tests/src/test/scala/cats/tests/SyntaxSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ object SyntaxSuite
val mtab2 = tmab.parLeftSequence
}

def testParallelFoldable[T[_]: Foldable, M[_]: Parallel, A, B: Monoid]: Unit = {
val ta = mock[T[A]]
val f = mock[A => M[B]]
val mb = ta.parFoldMapA(f)
}

def testReducible[F[_]: Reducible, G[_]: Apply: SemigroupK, A: Semigroup, B, Z]: Unit = {
val fa = mock[F[A]]
val f1 = mock[(A, A) => A]
Expand Down

0 comments on commit bd82ff2

Please sign in to comment.