-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Luka Jacobowitz
committed
Aug 21, 2017
1 parent
80a9853
commit 82b6ae7
Showing
2 changed files
with
92 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package cats | ||
|
||
trait Parallel[M[_], F[_]] { | ||
def applicative: Applicative[F] | ||
def sequential(implicit M: Monad[M]): F ~> M | ||
def parallel(implicit M: Monad[M]): M ~> F | ||
} | ||
|
||
object Parallel { | ||
def parSequence[T[_]: Traverse, M[_]: Monad, F[_], A] | ||
(tma: T[M[A]])(implicit P: Parallel[M, F]): M[T[A]] = { | ||
implicit val F = P.applicative | ||
val fta: F[T[A]] = Traverse[T].traverse(tma)(P.parallel.apply) | ||
P.sequential.apply(fta) | ||
} | ||
|
||
def parTraverse[T[_]: Traverse, M[_]: Monad, F[_], A, B] | ||
(ta: T[A])(f: A => M[B])(implicit P: Parallel[M, F]): M[T[B]] = { | ||
implicit val F = P.applicative | ||
val gtb: F[T[B]] = Traverse[T].traverse(ta)(f andThen P.parallel.apply) | ||
P.sequential.apply(gtb) | ||
} | ||
|
||
def parSequence_[T[_]: Foldable, M[_]: Monad, F[_], A] | ||
(tma: T[M[A]])(implicit P: Parallel[M, F]): M[Unit] = { | ||
implicit val F = P.applicative | ||
val fu: F[Unit] = Foldable[T].traverse_(tma)(P.parallel.apply) | ||
P.sequential.apply(fu) | ||
} | ||
|
||
def parTraverse_[T[_]: Foldable, M[_]: Monad, F[_], A, B] | ||
(ta: T[A])(f: A => M[B])(implicit P: Parallel[M, F]): M[Unit] = { | ||
implicit val F = P.applicative | ||
val gtb: F[Unit] = Foldable[T].traverse_(ta)(f andThen P.parallel.apply) | ||
P.sequential.apply(gtb) | ||
} | ||
|
||
def parAp[M[_]: Monad, F[_], A, B](mf: M[A => B]) | ||
(ma: M[A]) | ||
(implicit P: Parallel[M, F]): M[B] = { | ||
implicit val F = P.applicative | ||
val fb = Applicative[F].ap(P.parallel.apply(mf))(P.parallel.apply(ma)) | ||
P.sequential.apply(fb) | ||
} | ||
|
||
def parProduct[M[_]: Monad, F[_], A, B](ma: M[A], mb: M[B]) | ||
(implicit P: Parallel[M, F]): M[(A, B)] = | ||
parAp(Monad[M].map(ma)(a => (b: B) => (a, b)))(mb) | ||
|
||
def parAp2[M[_]: Monad, F[_], A, B, Z](ff: M[(A, B) => Z]) | ||
(ma: M[A], mb: M[B]) | ||
(implicit P: Parallel[M, F]): M[Z] = | ||
Monad[M].map(parProduct(ma, parProduct(mb, ff))) { case (a, (b, f)) => f(a, b) } | ||
|
||
def parMap2[M[_]: Monad, F[_], A, B, C](ma: M[A], mb: M[B]) | ||
(f: (A, B) => C) | ||
(implicit P: Parallel[M, F]): M[C] = { | ||
Monad[M].map(parProduct(ma, mb)) { case (a, b) => f(a, b) } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package cats.syntax | ||
|
||
import cats.{Monad, Parallel, Traverse} | ||
|
||
trait parallel { | ||
implicit final def catsSyntaxParallelTraverse[T[_]: Traverse, A] | ||
(ta: T[A]): ParallelTraversableOps[T, A] = new ParallelTraversableOps[T, A] { | ||
override def self = ta | ||
|
||
override val typeClassInstance: Traverse[T] = T | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
trait ParallelTraversableOps[T[_], A] { | ||
|
||
val typeClassInstance : cats.Traverse[T] | ||
def self : T[A] | ||
|
||
implicit val T = typeClassInstance | ||
|
||
def parTraverse[M[_]: Monad, F[_], B] | ||
(f: A => M[B])(implicit P: Parallel[M, F]): M[T[B]] = | ||
Parallel.parTraverse(self)(f) | ||
|
||
def parSequence[M[_]: Monad, F[_], B](implicit ev: A <:< M[B], P: Parallel[M, F]): M[T[B]] = | ||
Parallel.parSequence(self.asInstanceOf[T[M[B]]]) | ||
|
||
|
||
} |