cats-par
Parallel has 2 types instead of 1 despite the second type generally having a canonical instance. This uses an abstract type member to allow using a single type rather than 2. As suggestions have made and plans in place for this in cats 2.0 this is an intermediate solution that will be deprecated upon its release.
Reasoning
Temporary Solution For typelevel/cats#2233
Initial Credit to @johnnek for the idea
Quick Start
To use cats-par in an existing SBT project with Scala 2.11 or a later version, add the following dependency to your
build.sbt
:
libraryDependencies += "io.chrisdavenport" %% "cats-par" % "<version>"
Examples
import cats._
import cats.implicits._
import cats.data._
import cats.temp.par._
And then…
// Without This You Require a second type parameter and to continue, this second
// param up the entire call stack
def withoutPar[F[_]: Monad, G[_], A, C, D](as: List[A], f: A => Kleisli[F, C, D])
(implicit P: Parallel[F, G]): Kleisli[F, C, List[D]] =
as.parTraverse(f)
scala> // With This It Is Just Another Constraint on your Abstract F
| def withPar[F[_]: Monad : Par, A, C, D](as: List[A], f: A => Kleisli[F, C, D]): Kleisli[F, C, List[D]] =
| as.parTraverse(f)
withPar: [F[_], A, C, D](as: List[A], f: A => cats.data.Kleisli[F,C,D])(implicit evidence$1: cats.Monad[F], implicit evidence$2: cats.temp.par.Par[F])cats.data.Kleisli[F,C,List[D]]
scala> // Also Works For Instances Not in Core
| import cats.effect.IO
import cats.effect.IO
scala> implicit val contextShift = IO.contextShift(scala.concurrent.ExecutionContext.global)
contextShift: cats.effect.ContextShift[cats.effect.IO] = cats.effect.internals.IOContextShift@20f54d30
scala> (IO(1), IO(2)).parMapN(_ + _)
res2: cats.effect.IO[Int] = <function1>