Skip to content

Commit

Permalink
add par functions for Bitraverse
Browse files Browse the repository at this point in the history
  • Loading branch information
catostrophe committed Mar 17, 2019
1 parent d695904 commit 0922a78
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 2 deletions.
46 changes: 46 additions & 0 deletions core/src/main/scala/cats/Parallel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,52 @@ object Parallel extends ParallelArityFunctions2 {
P.sequential(gtb)
}

/**
* Like `Bitraverse[A].bitraverse`, but uses the applicative instance
* corresponding to the Parallel instance instead.
*/
def parBitraverse[T[_, _]: Bitraverse, M[_], F[_], A, B, C, D](
tab: T[A, B]
)(f: A => M[C], g: B => M[D])(implicit P: Parallel[M, F]): M[T[C, D]] = {
val ftcd: F[T[C, D]] =
Bitraverse[T].bitraverse(tab)(f.andThen(P.parallel.apply), g.andThen(P.parallel.apply))(P.applicative)
P.sequential(ftcd)
}

/**
* Like `Bitraverse[A].bisequence`, but uses the applicative instance
* corresponding to the Parallel instance instead.
*/
def parBisequence[T[_, _]: Bitraverse, M[_], F[_], A, B](
tmamb: T[M[A], M[B]]
)(implicit P: Parallel[M, F]): M[T[A, B]] = {
val ftab: F[T[A, B]] = Bitraverse[T].bitraverse(tmamb)(P.parallel.apply, P.parallel.apply)(P.applicative)
P.sequential(ftab)
}

/**
* Like `Bitraverse[A].leftTraverse`, but uses the applicative instance
* corresponding to the Parallel instance instead.
*/
def parLeftTraverse[T[_, _]: Bitraverse, M[_], F[_], A, B, C](
tab: T[A, B]
)(f: A => M[C])(implicit P: Parallel[M, F]): M[T[C, B]] = {
val ftcb: F[T[C, B]] =
Bitraverse[T].bitraverse(tab)(f.andThen(P.parallel.apply), P.applicative.pure)(P.applicative)
P.sequential(ftcb)
}

/**
* Like `Bitraverse[A].leftSequence`, but uses the applicative instance
* corresponding to the Parallel instance instead.
*/
def parLeftSequence[T[_, _]: Bitraverse, M[_], F[_], A, B](
tmab: T[M[A], B]
)(implicit P: Parallel[M, F]): M[T[A, B]] = {
val ftab: F[T[A, B]] = Bitraverse[T].bitraverse(tmab)(P.parallel.apply, P.applicative.pure)(P.applicative)
P.sequential(ftab)
}

/**
* Like `Applicative[F].ap`, but uses the applicative instance
* corresponding to the Parallel instance instead.
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/scala/cats/syntax/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ abstract class AllSyntaxBinCompat
with AllSyntaxBinCompat2
with AllSyntaxBinCompat3
with AllSyntaxBinCompat4
with AllSyntaxBinCompat5

trait AllSyntax
extends AlternativeSyntax
Expand Down Expand Up @@ -87,3 +88,5 @@ trait AllSyntaxBinCompat4
with ReducibleSyntaxBinCompat0
with FoldableSyntaxBinCompat1
with BitraverseSyntaxBinCompat0

trait AllSyntaxBinCompat5 extends ParallelBitraverseSyntax
7 changes: 6 additions & 1 deletion core/src/main/scala/cats/syntax/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ package object syntax {
object nested extends NestedSyntax
object option extends OptionSyntax
object order extends OrderSyntax
object parallel extends ParallelSyntax with ParallelTraverseSyntax with ParallelFlatSyntax with ParallelApplySyntax
object parallel
extends ParallelSyntax
with ParallelTraverseSyntax
with ParallelFlatSyntax
with ParallelApplySyntax
with ParallelBitraverseSyntax
object partialOrder extends PartialOrderSyntax
object profunctor extends ProfunctorSyntax
object reducible extends ReducibleSyntax with ReducibleSyntaxBinCompat0
Expand Down
45 changes: 44 additions & 1 deletion core/src/main/scala/cats/syntax/parallel.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cats.syntax

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

trait ParallelSyntax extends TupleParallelSyntax {

Expand Down Expand Up @@ -39,6 +39,28 @@ trait ParallelTraverseSyntax {
new ParallelSequence_Ops[T, M, A](tma)
}

trait ParallelBitraverseSyntax {
implicit final def catsSyntaxParallelBitraverse[T[_, _]: Bitraverse, A, B](
tab: T[A, B]
): ParallelBitraverseOps[T, A, B] =
new ParallelBitraverseOps[T, A, B](tab)

implicit final def catsSyntaxParallelBisequence[T[_, _]: Bitraverse, M[_], A, B](
tmamb: T[M[A], M[B]]
): ParallelBisequenceOps[T, M, A, B] =
new ParallelBisequenceOps[T, M, A, B](tmamb)

implicit final def catsSyntaxParallelLeftTraverse[T[_, _]: Bitraverse, A, B](
tab: T[A, B]
): ParallelLeftTraverseOps[T, A, B] =
new ParallelLeftTraverseOps[T, A, B](tab)

implicit final def catsSyntaxParallelLeftSequence[T[_, _]: Bitraverse, M[_], A, B](
tmab: T[M[A], B]
): ParallelLeftSequenceOps[T, M, A, B] =
new ParallelLeftSequenceOps[T, M, A, B](tmab)
}

final class ParallelTraversableOps[T[_], A](private val ta: T[A]) extends AnyVal {
def parTraverse[M[_]: Monad, F[_], B](f: A => M[B])(implicit T: Traverse[T], P: Parallel[M, F]): M[T[B]] =
Parallel.parTraverse(ta)(f)
Expand Down Expand Up @@ -86,3 +108,24 @@ final class ParallelApplyOps[M[_], A, B](private val mab: M[A => B]) extends Any
def <&>[F[_]](ma: M[A])(implicit P: Parallel[M, F]): M[B] =
Parallel.parAp(mab)(ma)
}

final class ParallelBitraverseOps[T[_, _], A, B](private val tab: T[A, B]) extends AnyVal {
def parBitraverse[M[_], F[_], C, D](f: A => M[C], g: B => M[D])(implicit T: Bitraverse[T],
P: Parallel[M, F]): M[T[C, D]] =
Parallel.parBitraverse(tab)(f, g)
}

final class ParallelBisequenceOps[T[_, _], M[_], A, B](private val tmamb: T[M[A], M[B]]) extends AnyVal {
def parBisequence[F[_]](implicit T: Bitraverse[T], P: Parallel[M, F]): M[T[A, B]] =
Parallel.parBisequence(tmamb)
}

final class ParallelLeftTraverseOps[T[_, _], A, B](private val tab: T[A, B]) extends AnyVal {
def parLeftTraverse[M[_], F[_], C](f: A => M[C])(implicit T: Bitraverse[T], P: Parallel[M, F]): M[T[C, B]] =
Parallel.parLeftTraverse(tab)(f)
}

final class ParallelLeftSequenceOps[T[_, _], M[_], A, B](private val tmab: T[M[A], B]) extends AnyVal {
def parLeftSequence[F[_]](implicit T: Bitraverse[T], P: Parallel[M, F]): M[T[A, B]] =
Parallel.parLeftSequence(tmab)
}
1 change: 1 addition & 0 deletions testkit/src/main/scala/cats/tests/CatsSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ trait CatsSuite
with AllSyntaxBinCompat2
with AllSyntaxBinCompat3
with AllSyntaxBinCompat4
with AllSyntaxBinCompat5
with StrictCatsEquality { self: FunSuiteLike =>

implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
Expand Down
12 changes: 12 additions & 0 deletions tests/src/test/scala/cats/tests/ParallelSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest {
}
}

test("ParBitraverse identity should be equivalent to parBisequence") {
forAll { es: (Either[String, Int], Either[String, Long]) =>
es.parBitraverse(identity, identity) should ===(es.parBisequence)
}
}

test("ParLeftTraverse identity should be equivalent to parLeftSequence") {
forAll { es: (Either[String, Int], Either[String, Long]) =>
es.parLeftTraverse(identity) should ===(es.parLeftSequence)
}
}

test("ParFlatTraverse should be equivalent to parTraverse map flatten") {
forAll { es: List[Either[String, Int]] =>
val f: Int => List[Int] = i => List(i, i + 1)
Expand Down
14 changes: 14 additions & 0 deletions tests/src/test/scala/cats/tests/SyntaxSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,20 @@ object SyntaxSuite
(fa, fb, fc).parMapN(f)
}

def testParallelBi[M[_], F[_], T[_, _]: Bitraverse, A, B, C, D](implicit P: Parallel[M, F]): Unit = {
val tab = mock[T[A, B]]
val f = mock[A => M[C]]
val g = mock[B => M[D]]
val mtcd = tab.parBitraverse(f, g)
val mtcb = tab.parLeftTraverse(f)

val tmamb = mock[T[M[A], M[B]]]
val mtab1 = tmamb.parBisequence

val tmab = mock[T[M[A], B]]
val mtab2 = tmab.parLeftSequence
}

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 0922a78

Please sign in to comment.