diff --git a/core/src/main/scala-2.12-/cats/instances/ScalaVersionSpecificParallelInstances.scala b/core/src/main/scala-2.12-/cats/instances/ScalaVersionSpecificParallelInstances.scala index e572d9c8e9..1799c9ebfb 100644 --- a/core/src/main/scala-2.12-/cats/instances/ScalaVersionSpecificParallelInstances.scala +++ b/core/src/main/scala-2.12-/cats/instances/ScalaVersionSpecificParallelInstances.scala @@ -7,8 +7,9 @@ import cats.syntax.either._ import cats.{~>, Applicative, Apply, FlatMap, Functor, Monad, NonEmptyParallel, Parallel} trait ParallelInstances extends ParallelInstances1 { - implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel[Either[E, *], Validated[E, *]] = - new Parallel[Either[E, *], Validated[E, *]] { + implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel.Aux[Either[E, *], Validated[E, *]] = + new Parallel[Either[E, *]] { + type F[x] = Validated[E, x] def applicative: Applicative[Validated[E, *]] = Validated.catsDataApplicativeErrorForValidated def monad: Monad[Either[E, *]] = cats.instances.either.catsStdInstancesForEither @@ -20,27 +21,28 @@ trait ParallelInstances extends ParallelInstances1 { λ[Either[E, *] ~> Validated[E, *]](_.toValidated) } - implicit def catsParallelForOptionTNestedOption[F[_], M[_]]( - implicit P: Parallel[M, F] - ): Parallel[OptionT[M, *], Nested[F, Option, *]] = new Parallel[OptionT[M, *], Nested[F, Option, *]] { + implicit def catsParallelForOptionTNestedOption[M[_]]( + implicit P: Parallel[M] + ): Parallel.Aux[OptionT[M, *], Nested[P.F, Option, *]] = new Parallel[OptionT[M, *]] { + type F[x] = Nested[P.F, Option, x] - implicit val appF: Applicative[F] = P.applicative implicit val monadM: Monad[M] = P.monad - implicit val appOption: Applicative[Option] = cats.instances.option.catsStdInstancesForOption - def applicative: Applicative[Nested[F, Option, *]] = cats.data.Nested.catsDataApplicativeForNested[F, Option] + def applicative: Applicative[Nested[P.F, Option, *]] = + cats.data.Nested.catsDataApplicativeForNested(P.applicative, cats.instances.option.catsStdInstancesForOption) def monad: Monad[OptionT[M, *]] = cats.data.OptionT.catsDataMonadErrorMonadForOptionT[M] - def sequential: Nested[F, Option, *] ~> OptionT[M, *] = - λ[Nested[F, Option, *] ~> OptionT[M, *]](nested => OptionT(P.sequential(nested.value))) + def sequential: Nested[P.F, Option, *] ~> OptionT[M, *] = + λ[Nested[P.F, Option, *] ~> OptionT[M, *]](nested => OptionT(P.sequential(nested.value))) - def parallel: OptionT[M, *] ~> Nested[F, Option, *] = - λ[OptionT[M, *] ~> Nested[F, Option, *]](optT => Nested(P.parallel(optT.value))) + def parallel: OptionT[M, *] ~> Nested[P.F, Option, *] = + λ[OptionT[M, *] ~> Nested[P.F, Option, *]](optT => Nested(P.parallel(optT.value))) } - implicit def catsStdNonEmptyParallelForZipList[A]: NonEmptyParallel[List, ZipList] = - new NonEmptyParallel[List, ZipList] { + implicit def catsStdNonEmptyParallelForZipList[A]: NonEmptyParallel.Aux[List, ZipList] = + new NonEmptyParallel[List] { + type F[x] = ZipList[x] def flatMap: FlatMap[List] = cats.instances.list.catsStdInstancesForList def apply: Apply[ZipList] = ZipList.catsDataCommutativeApplyForZipList @@ -52,8 +54,9 @@ trait ParallelInstances extends ParallelInstances1 { λ[List ~> ZipList](v => new ZipList(v)) } - implicit def catsStdNonEmptyParallelForZipVector[A]: NonEmptyParallel[Vector, ZipVector] = - new NonEmptyParallel[Vector, ZipVector] { + implicit def catsStdNonEmptyParallelForZipVector[A]: NonEmptyParallel.Aux[Vector, ZipVector] = + new NonEmptyParallel[Vector] { + type F[x] = ZipVector[x] def flatMap: FlatMap[Vector] = cats.instances.vector.catsStdInstancesForVector def apply: Apply[ZipVector] = ZipVector.catsDataCommutativeApplyForZipVector @@ -65,8 +68,9 @@ trait ParallelInstances extends ParallelInstances1 { λ[Vector ~> ZipVector](v => new ZipVector(v)) } - implicit def catsStdParallelForZipStream[A]: Parallel[Stream, ZipStream] = - new Parallel[Stream, ZipStream] { + implicit def catsStdParallelForZipStream[A]: Parallel.Aux[Stream, ZipStream] = + new Parallel[Stream] { + type F[x] = ZipStream[x] def monad: Monad[Stream] = cats.instances.stream.catsStdInstancesForStream def applicative: Applicative[ZipStream] = ZipStream.catsDataAlternativeForZipStream @@ -78,31 +82,30 @@ trait ParallelInstances extends ParallelInstances1 { λ[Stream ~> ZipStream](v => new ZipStream(v)) } - implicit def catsParallelForEitherTNestedParallelValidated[F[_], M[_], E: Semigroup]( - implicit P: Parallel[M, F] - ): Parallel[EitherT[M, E, *], Nested[F, Validated[E, *], *]] = - new Parallel[EitherT[M, E, *], Nested[F, Validated[E, *], *]] { + implicit def catsParallelForEitherTNestedParallelValidated[M[_], E: Semigroup]( + implicit P: Parallel[M] + ): Parallel.Aux[EitherT[M, E, *], Nested[P.F, Validated[E, *], *]] = + new Parallel[EitherT[M, E, *]] { + type F[x] = Nested[P.F, Validated[E, *], x] - implicit val appF: Applicative[F] = P.applicative implicit val monadM: Monad[M] = P.monad - implicit val appValidated: Applicative[Validated[E, *]] = Validated.catsDataApplicativeErrorForValidated implicit val monadEither: Monad[Either[E, *]] = cats.instances.either.catsStdInstancesForEither - def applicative: Applicative[Nested[F, Validated[E, *], *]] = - cats.data.Nested.catsDataApplicativeForNested[F, Validated[E, *]] + def applicative: Applicative[Nested[P.F, Validated[E, *], *]] = + cats.data.Nested.catsDataApplicativeForNested(P.applicative, Validated.catsDataApplicativeErrorForValidated) def monad: Monad[EitherT[M, E, *]] = cats.data.EitherT.catsDataMonadErrorForEitherT - def sequential: Nested[F, Validated[E, *], *] ~> EitherT[M, E, *] = - λ[Nested[F, Validated[E, *], *] ~> EitherT[M, E, *]] { nested => + def sequential: Nested[P.F, Validated[E, *], *] ~> EitherT[M, E, *] = + λ[Nested[P.F, Validated[E, *], *] ~> EitherT[M, E, *]] { nested => val mva = P.sequential(nested.value) EitherT(Functor[M].map(mva)(_.toEither)) } - def parallel: EitherT[M, E, *] ~> Nested[F, Validated[E, *], *] = - λ[EitherT[M, E, *] ~> Nested[F, Validated[E, *], *]] { eitherT => + def parallel: EitherT[M, E, *] ~> Nested[P.F, Validated[E, *], *] = + λ[EitherT[M, E, *] ~> Nested[P.F, Validated[E, *], *]] { eitherT => val fea = P.parallel(eitherT.value) - Nested(Functor[F].map(fea)(_.toValidated)) + Nested(P.applicative.map(fea)(_.toValidated)) } } } diff --git a/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala b/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala index ab6ec6e3a0..2cbed1312d 100644 --- a/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala +++ b/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala @@ -364,8 +364,9 @@ sealed abstract private[data] class NonEmptyLazyListInstances extends NonEmptyLa implicit def catsDataShowForNonEmptyLazyList[A](implicit A: Show[A]): Show[NonEmptyLazyList[A]] = Show.show[NonEmptyLazyList[A]](nell => s"NonEmpty${Show[LazyList[A]].show(nell.toLazyList)}") - implicit def catsDataParallelForNonEmptyLazyList: Parallel[NonEmptyLazyList, OneAnd[ZipLazyList, *]] = - new Parallel[NonEmptyLazyList, OneAnd[ZipLazyList, *]] { + implicit def catsDataParallelForNonEmptyLazyList: Parallel.Aux[NonEmptyLazyList, OneAnd[ZipLazyList, *]] = + new Parallel[NonEmptyLazyList] { + type F[x] = OneAnd[ZipLazyList, x] def applicative: Applicative[OneAnd[ZipLazyList, *]] = OneAnd.catsDataApplicativeForOneAnd(ZipLazyList.catsDataAlternativeForZipLazyList) diff --git a/core/src/main/scala-2.13+/cats/instances/ScalaVersionSpecificParallelInstances.scala b/core/src/main/scala-2.13+/cats/instances/ScalaVersionSpecificParallelInstances.scala index 98110dea19..4f0400ba4b 100644 --- a/core/src/main/scala-2.13+/cats/instances/ScalaVersionSpecificParallelInstances.scala +++ b/core/src/main/scala-2.13+/cats/instances/ScalaVersionSpecificParallelInstances.scala @@ -7,8 +7,9 @@ import cats.syntax.either._ import cats.{~>, Applicative, Apply, FlatMap, Functor, Monad, NonEmptyParallel, Parallel} trait ParallelInstances extends ParallelInstances1 { - implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel[Either[E, *], Validated[E, *]] = - new Parallel[Either[E, *], Validated[E, *]] { + implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel.Aux[Either[E, *], Validated[E, *]] = + new Parallel[Either[E, *]] { + type F[x] = Validated[E, x] def applicative: Applicative[Validated[E, *]] = Validated.catsDataApplicativeErrorForValidated def monad: Monad[Either[E, *]] = cats.instances.either.catsStdInstancesForEither @@ -20,27 +21,28 @@ trait ParallelInstances extends ParallelInstances1 { λ[Either[E, *] ~> Validated[E, *]](_.toValidated) } - implicit def catsParallelForOptionTNestedOption[F[_], M[_]]( - implicit P: Parallel[M, F] - ): Parallel[OptionT[M, *], Nested[F, Option, *]] = new Parallel[OptionT[M, *], Nested[F, Option, *]] { + implicit def catsParallelForOptionTNestedOption[M[_]]( + implicit P: Parallel[M] + ): Parallel.Aux[OptionT[M, *], Nested[P.F, Option, *]] = new Parallel[OptionT[M, *]] { + type F[x] = Nested[P.F, Option, x] - implicit val appF: Applicative[F] = P.applicative implicit val monadM: Monad[M] = P.monad - implicit val appOption: Applicative[Option] = cats.instances.option.catsStdInstancesForOption - def applicative: Applicative[Nested[F, Option, *]] = cats.data.Nested.catsDataApplicativeForNested[F, Option] + def applicative: Applicative[Nested[P.F, Option, *]] = + cats.data.Nested.catsDataApplicativeForNested(P.applicative, cats.instances.option.catsStdInstancesForOption) def monad: Monad[OptionT[M, *]] = cats.data.OptionT.catsDataMonadErrorMonadForOptionT[M] - def sequential: Nested[F, Option, *] ~> OptionT[M, *] = - λ[Nested[F, Option, *] ~> OptionT[M, *]](nested => OptionT(P.sequential(nested.value))) + def sequential: Nested[P.F, Option, *] ~> OptionT[M, *] = + λ[Nested[P.F, Option, *] ~> OptionT[M, *]](nested => OptionT(P.sequential(nested.value))) - def parallel: OptionT[M, *] ~> Nested[F, Option, *] = - λ[OptionT[M, *] ~> Nested[F, Option, *]](optT => Nested(P.parallel(optT.value))) + def parallel: OptionT[M, *] ~> Nested[P.F, Option, *] = + λ[OptionT[M, *] ~> Nested[P.F, Option, *]](optT => Nested(P.parallel(optT.value))) } - implicit def catsStdNonEmptyParallelForZipList[A]: NonEmptyParallel[List, ZipList] = - new NonEmptyParallel[List, ZipList] { + implicit def catsStdNonEmptyParallelForZipList[A]: NonEmptyParallel.Aux[List, ZipList] = + new NonEmptyParallel[List] { + type F[x] = ZipList[x] def flatMap: FlatMap[List] = cats.instances.list.catsStdInstancesForList def apply: Apply[ZipList] = ZipList.catsDataCommutativeApplyForZipList @@ -52,8 +54,9 @@ trait ParallelInstances extends ParallelInstances1 { λ[List ~> ZipList](v => new ZipList(v)) } - implicit def catsStdNonEmptyParallelForZipVector[A]: NonEmptyParallel[Vector, ZipVector] = - new NonEmptyParallel[Vector, ZipVector] { + implicit def catsStdNonEmptyParallelForZipVector[A]: NonEmptyParallel.Aux[Vector, ZipVector] = + new NonEmptyParallel[Vector] { + type F[x] = ZipVector[x] def flatMap: FlatMap[Vector] = cats.instances.vector.catsStdInstancesForVector def apply: Apply[ZipVector] = ZipVector.catsDataCommutativeApplyForZipVector @@ -66,8 +69,9 @@ trait ParallelInstances extends ParallelInstances1 { } @deprecated("Use catsStdParallelForZipLazyList", "2.0.0-RC2") - implicit def catsStdParallelForZipStream[A]: Parallel[Stream, ZipStream] = - new Parallel[Stream, ZipStream] { + implicit def catsStdParallelForZipStream[A]: Parallel.Aux[Stream, ZipStream] = + new Parallel[Stream] { + type F[x] = ZipStream[x] def monad: Monad[Stream] = cats.instances.stream.catsStdInstancesForStream def applicative: Applicative[ZipStream] = ZipStream.catsDataAlternativeForZipStream @@ -79,8 +83,9 @@ trait ParallelInstances extends ParallelInstances1 { λ[Stream ~> ZipStream](v => new ZipStream(v)) } - implicit def catsStdParallelForZipLazyList[A]: Parallel[LazyList, ZipLazyList] = - new Parallel[LazyList, ZipLazyList] { + implicit def catsStdParallelForZipLazyList[A]: Parallel.Aux[LazyList, ZipLazyList] = + new Parallel[LazyList] { + type F[x] = ZipLazyList[x] def monad: Monad[LazyList] = cats.instances.lazyList.catsStdInstancesForLazyList def applicative: Applicative[ZipLazyList] = ZipLazyList.catsDataAlternativeForZipLazyList @@ -92,31 +97,30 @@ trait ParallelInstances extends ParallelInstances1 { λ[LazyList ~> ZipLazyList](v => new ZipLazyList(v)) } - implicit def catsParallelForEitherTNestedParallelValidated[F[_], M[_], E: Semigroup]( - implicit P: Parallel[M, F] - ): Parallel[EitherT[M, E, *], Nested[F, Validated[E, *], *]] = - new Parallel[EitherT[M, E, *], Nested[F, Validated[E, *], *]] { + implicit def catsParallelForEitherTNestedParallelValidated[M[_], E: Semigroup]( + implicit P: Parallel[M] + ): Parallel.Aux[EitherT[M, E, *], Nested[P.F, Validated[E, *], *]] = + new Parallel[EitherT[M, E, *]] { + type F[x] = Nested[P.F, Validated[E, *], x] - implicit val appF: Applicative[F] = P.applicative implicit val monadM: Monad[M] = P.monad - implicit val appValidated: Applicative[Validated[E, *]] = Validated.catsDataApplicativeErrorForValidated implicit val monadEither: Monad[Either[E, *]] = cats.instances.either.catsStdInstancesForEither - def applicative: Applicative[Nested[F, Validated[E, *], *]] = - cats.data.Nested.catsDataApplicativeForNested[F, Validated[E, *]] + def applicative: Applicative[Nested[P.F, Validated[E, *], *]] = + cats.data.Nested.catsDataApplicativeForNested(P.applicative, Validated.catsDataApplicativeErrorForValidated) def monad: Monad[EitherT[M, E, *]] = cats.data.EitherT.catsDataMonadErrorForEitherT - def sequential: Nested[F, Validated[E, *], *] ~> EitherT[M, E, *] = - λ[Nested[F, Validated[E, *], *] ~> EitherT[M, E, *]] { nested => + def sequential: Nested[P.F, Validated[E, *], *] ~> EitherT[M, E, *] = + λ[Nested[P.F, Validated[E, *], *] ~> EitherT[M, E, *]] { nested => val mva = P.sequential(nested.value) EitherT(Functor[M].map(mva)(_.toEither)) } - def parallel: EitherT[M, E, *] ~> Nested[F, Validated[E, *], *] = - λ[EitherT[M, E, *] ~> Nested[F, Validated[E, *], *]] { eitherT => + def parallel: EitherT[M, E, *] ~> Nested[P.F, Validated[E, *], *] = + λ[EitherT[M, E, *] ~> Nested[P.F, Validated[E, *], *]] { eitherT => val fea = P.parallel(eitherT.value) - Nested(Functor[F].map(fea)(_.toValidated)) + Nested(P.applicative.map(fea)(_.toValidated)) } } } diff --git a/core/src/main/scala/cats/Parallel.scala b/core/src/main/scala/cats/Parallel.scala index 466b172f81..bd41a97323 100644 --- a/core/src/main/scala/cats/Parallel.scala +++ b/core/src/main/scala/cats/Parallel.scala @@ -6,7 +6,8 @@ import cats.arrow.FunctionK * Some types that form a FlatMap, are also capable of forming an Apply that supports parallel composition. * The NonEmptyParallel type class allows us to represent this relationship. */ -trait NonEmptyParallel[M[_], F[_]] extends Serializable { +trait NonEmptyParallel[M[_]] extends Serializable { + type F[_] /** * The Apply instance for F[_] @@ -54,7 +55,7 @@ trait NonEmptyParallel[M[_], F[_]] extends Serializable { * Some types that form a Monad, are also capable of forming an Applicative that supports parallel composition. * The Parallel type class allows us to represent this relationship. */ -trait Parallel[M[_], F[_]] extends NonEmptyParallel[M, F] { +trait Parallel[M[_]] extends NonEmptyParallel[M] { /** * The applicative instance for F[_] @@ -71,7 +72,7 @@ trait Parallel[M[_], F[_]] extends NonEmptyParallel[M, F] { override def flatMap: FlatMap[M] = monad /** - * Provides an `ApplicativeError[F, E]` instance for any F, that has a `Parallel[M, F]` + * Provides an `ApplicativeError[F, E]` instance for any F, that has a `Parallel.Aux[M, F]` * and a `MonadError[M, E]` instance. * I.e. if you have a type M[_], that supports parallel composition through type F[_], * then you can get `ApplicativeError[F, E]` from `MonadError[M, E]`. @@ -106,19 +107,22 @@ trait Parallel[M[_], F[_]] extends NonEmptyParallel[M, F] { } object NonEmptyParallel { - def apply[M[_], F[_]](implicit P: NonEmptyParallel[M, F]): NonEmptyParallel[M, F] = P + type Aux[M[_], F0[_]] = NonEmptyParallel[M] { type F[x] = F0[x] } + + def apply[M[_], F[_]](implicit P: NonEmptyParallel.Aux[M, F]): NonEmptyParallel.Aux[M, F] = P } object Parallel extends ParallelArityFunctions2 { + type Aux[M[_], F0[_]] = Parallel[M] { type F[x] = F0[x] } - def apply[M[_], F[_]](implicit P: Parallel[M, F]): Parallel[M, F] = P + def apply[M[_], F[_]](implicit P: Parallel.Aux[M, F]): Parallel.Aux[M, F] = P /** * Like `Traverse[A].sequence`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parSequence[T[_]: Traverse, M[_], F[_], A](tma: T[M[A]])(implicit P: Parallel[M, F]): M[T[A]] = { - val fta: F[T[A]] = Traverse[T].traverse(tma)(P.parallel.apply)(P.applicative) + def parSequence[T[_]: Traverse, M[_], A](tma: T[M[A]])(implicit P: Parallel[M]): M[T[A]] = { + val fta: P.F[T[A]] = Traverse[T].traverse(tma)(P.parallel.apply(_))(P.applicative) P.sequential(fta) } @@ -126,8 +130,8 @@ object Parallel extends ParallelArityFunctions2 { * Like `Traverse[A].traverse`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parTraverse[T[_]: Traverse, M[_], F[_], A, B](ta: T[A])(f: A => M[B])(implicit P: Parallel[M, F]): M[T[B]] = { - val gtb: F[T[B]] = Traverse[T].traverse(ta)(f.andThen(P.parallel.apply))(P.applicative) + def parTraverse[T[_]: Traverse, M[_], A, B](ta: T[A])(f: A => M[B])(implicit P: Parallel[M]): M[T[B]] = { + val gtb: P.F[T[B]] = Traverse[T].traverse(ta)(f.andThen(P.parallel.apply(_)))(P.applicative) P.sequential(gtb) } @@ -135,10 +139,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `Traverse[A].flatTraverse`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parFlatTraverse[T[_]: Traverse: FlatMap, M[_], F[_], A, B]( + def parFlatTraverse[T[_]: Traverse: FlatMap, M[_], A, B]( ta: T[A] - )(f: A => M[T[B]])(implicit P: Parallel[M, F]): M[T[B]] = { - val gtb: F[T[B]] = Traverse[T].flatTraverse(ta)(f.andThen(P.parallel.apply))(P.applicative, FlatMap[T]) + )(f: A => M[T[B]])(implicit P: Parallel[M]): M[T[B]] = { + val gtb: P.F[T[B]] = Traverse[T].flatTraverse(ta)(f.andThen(P.parallel.apply(_)))(P.applicative, FlatMap[T]) P.sequential(gtb) } @@ -146,8 +150,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `Traverse[A].flatSequence`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parFlatSequence[T[_]: Traverse: FlatMap, M[_], F[_], A](tma: T[M[T[A]]])(implicit P: Parallel[M, F]): M[T[A]] = { - val fta: F[T[A]] = Traverse[T].flatTraverse(tma)(P.parallel.apply)(P.applicative, FlatMap[T]) + def parFlatSequence[T[_]: Traverse: FlatMap, M[_], A]( + tma: T[M[T[A]]] + )(implicit P: Parallel[M]): M[T[A]] = { + val fta: P.F[T[A]] = Traverse[T].flatTraverse(tma)(P.parallel.apply(_))(P.applicative, FlatMap[T]) P.sequential(fta) } @@ -155,8 +161,8 @@ object Parallel extends ParallelArityFunctions2 { * Like `Foldable[A].sequence_`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parSequence_[T[_]: Foldable, M[_], F[_], A](tma: T[M[A]])(implicit P: Parallel[M, F]): M[Unit] = { - val fu: F[Unit] = Foldable[T].traverse_(tma)(P.parallel.apply)(P.applicative) + def parSequence_[T[_]: Foldable, M[_], A](tma: T[M[A]])(implicit P: Parallel[M]): M[Unit] = { + val fu: P.F[Unit] = Foldable[T].traverse_(tma)(P.parallel.apply(_))(P.applicative) P.sequential(fu) } @@ -164,39 +170,41 @@ object Parallel extends ParallelArityFunctions2 { * Like `Foldable[A].traverse_`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parTraverse_[T[_]: Foldable, M[_], F[_], A, B](ta: T[A])(f: A => M[B])(implicit P: Parallel[M, F]): M[Unit] = { - val gtb: F[Unit] = Foldable[T].traverse_(ta)(f.andThen(P.parallel.apply))(P.applicative) + def parTraverse_[T[_]: Foldable, M[_], A, B]( + ta: T[A] + )(f: A => M[B])(implicit P: Parallel[M]): M[Unit] = { + val gtb: P.F[Unit] = Foldable[T].traverse_(ta)(f.andThen(P.parallel.apply(_)))(P.applicative) P.sequential(gtb) } def parUnorderedTraverse[T[_]: UnorderedTraverse, M[_], F[_]: CommutativeApplicative, A, B]( ta: T[A] - )(f: A => M[B])(implicit P: Parallel[M, F]): M[T[B]] = + )(f: A => M[B])(implicit P: Parallel.Aux[M, F]): M[T[B]] = P.sequential(UnorderedTraverse[T].unorderedTraverse(ta)(a => P.parallel(f(a)))) def parUnorderedSequence[T[_]: UnorderedTraverse, M[_], F[_]: CommutativeApplicative, A]( ta: T[M[A]] - )(implicit P: Parallel[M, F]): M[T[A]] = + )(implicit P: Parallel.Aux[M, F]): M[T[A]] = parUnorderedTraverse[T, M, F, M[A], A](ta)(Predef.identity) def parUnorderedFlatTraverse[T[_]: UnorderedTraverse: FlatMap, M[_], F[_]: CommutativeApplicative, A, B]( ta: T[A] - )(f: A => M[T[B]])(implicit P: Parallel[M, F]): M[T[B]] = + )(f: A => M[T[B]])(implicit P: Parallel.Aux[M, F]): M[T[B]] = P.monad.map(parUnorderedTraverse[T, M, F, A, T[B]](ta)(f))(FlatMap[T].flatten) def parUnorderedFlatSequence[T[_]: UnorderedTraverse: FlatMap, M[_], F[_]: CommutativeApplicative, A]( ta: T[M[T[A]]] - )(implicit P: Parallel[M, F]): M[T[A]] = + )(implicit P: Parallel.Aux[M, F]): M[T[A]] = parUnorderedFlatTraverse[T, M, F, M[T[A]], A](ta)(Predef.identity) /** * Like `NonEmptyTraverse[A].nonEmptySequence`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptySequence[T[_]: NonEmptyTraverse, M[_], F[_], A]( + def parNonEmptySequence[T[_]: NonEmptyTraverse, M[_], A]( tma: T[M[A]] - )(implicit P: NonEmptyParallel[M, F]): M[T[A]] = { - val fta: F[T[A]] = NonEmptyTraverse[T].nonEmptyTraverse(tma)(P.parallel.apply)(P.apply) + )(implicit P: NonEmptyParallel[M]): M[T[A]] = { + val fta: P.F[T[A]] = NonEmptyTraverse[T].nonEmptyTraverse(tma)(P.parallel.apply(_))(P.apply) P.sequential(fta) } @@ -204,10 +212,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `NonEmptyTraverse[A].nonEmptyTraverse`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptyTraverse[T[_]: NonEmptyTraverse, M[_], F[_], A, B]( + def parNonEmptyTraverse[T[_]: NonEmptyTraverse, M[_], A, B]( ta: T[A] - )(f: A => M[B])(implicit P: NonEmptyParallel[M, F]): M[T[B]] = { - val gtb: F[T[B]] = NonEmptyTraverse[T].nonEmptyTraverse(ta)(f.andThen(P.parallel.apply))(P.apply) + )(f: A => M[B])(implicit P: NonEmptyParallel[M]): M[T[B]] = { + val gtb: P.F[T[B]] = NonEmptyTraverse[T].nonEmptyTraverse(ta)(f.andThen(P.parallel.apply(_)))(P.apply) P.sequential(gtb) } @@ -215,10 +223,11 @@ object Parallel extends ParallelArityFunctions2 { * Like `NonEmptyTraverse[A].nonEmptyFlatTraverse`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptyFlatTraverse[T[_]: NonEmptyTraverse: FlatMap, M[_], F[_], A, B]( + def parNonEmptyFlatTraverse[T[_]: NonEmptyTraverse: FlatMap, M[_], A, B]( ta: T[A] - )(f: A => M[T[B]])(implicit P: NonEmptyParallel[M, F]): M[T[B]] = { - val gtb: F[T[B]] = NonEmptyTraverse[T].nonEmptyFlatTraverse(ta)(f.andThen(P.parallel.apply))(P.apply, FlatMap[T]) + )(f: A => M[T[B]])(implicit P: NonEmptyParallel[M]): M[T[B]] = { + val gtb: P.F[T[B]] = + NonEmptyTraverse[T].nonEmptyFlatTraverse(ta)(f.andThen(P.parallel.apply(_)))(P.apply, FlatMap[T]) P.sequential(gtb) } @@ -226,10 +235,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `NonEmptyTraverse[A].nonEmptyFlatSequence`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptyFlatSequence[T[_]: NonEmptyTraverse: FlatMap, M[_], F[_], A]( + def parNonEmptyFlatSequence[T[_]: NonEmptyTraverse: FlatMap, M[_], A]( tma: T[M[T[A]]] - )(implicit P: NonEmptyParallel[M, F]): M[T[A]] = { - val fta: F[T[A]] = NonEmptyTraverse[T].nonEmptyFlatTraverse(tma)(P.parallel.apply)(P.apply, FlatMap[T]) + )(implicit P: NonEmptyParallel[M]): M[T[A]] = { + val fta: P.F[T[A]] = NonEmptyTraverse[T].nonEmptyFlatTraverse(tma)(P.parallel.apply(_))(P.apply, FlatMap[T]) P.sequential(fta) } @@ -237,10 +246,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `Reducible[A].nonEmptySequence_`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptySequence_[T[_]: Reducible, M[_], F[_], A]( + def parNonEmptySequence_[T[_]: Reducible, M[_], A]( tma: T[M[A]] - )(implicit P: NonEmptyParallel[M, F]): M[Unit] = { - val fu: F[Unit] = Reducible[T].nonEmptyTraverse_(tma)(P.parallel.apply)(P.apply) + )(implicit P: NonEmptyParallel[M]): M[Unit] = { + val fu: P.F[Unit] = Reducible[T].nonEmptyTraverse_(tma)(P.parallel.apply(_))(P.apply) P.sequential(fu) } @@ -248,10 +257,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `Reducible[A].nonEmptyTraverse_`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptyTraverse_[T[_]: Reducible, M[_], F[_], A, B]( + def parNonEmptyTraverse_[T[_]: Reducible, M[_], A, B]( ta: T[A] - )(f: A => M[B])(implicit P: NonEmptyParallel[M, F]): M[Unit] = { - val gtb: F[Unit] = Reducible[T].nonEmptyTraverse_(ta)(f.andThen(P.parallel.apply))(P.apply) + )(f: A => M[B])(implicit P: NonEmptyParallel[M]): M[Unit] = { + val gtb: P.F[Unit] = Reducible[T].nonEmptyTraverse_(ta)(f.andThen(P.parallel.apply(_)))(P.apply) P.sequential(gtb) } @@ -259,11 +268,11 @@ object Parallel extends ParallelArityFunctions2 { * 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]( + def parBitraverse[T[_, _]: Bitraverse, M[_], 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) + )(f: A => M[C], g: B => M[D])(implicit P: Parallel[M]): M[T[C, D]] = { + val ftcd: P.F[T[C, D]] = + Bitraverse[T].bitraverse(tab)(f.andThen(P.parallel.apply(_)), g.andThen(P.parallel.apply(_)))(P.applicative) P.sequential(ftcd) } @@ -271,10 +280,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `Bitraverse[A].bisequence`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parBisequence[T[_, _]: Bitraverse, M[_], F[_], A, B]( + def parBisequence[T[_, _]: Bitraverse, M[_], 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) + )(implicit P: Parallel[M]): M[T[A, B]] = { + val ftab: P.F[T[A, B]] = Bitraverse[T].bitraverse(tmamb)(P.parallel.apply(_), P.parallel.apply(_))(P.applicative) P.sequential(ftab) } @@ -282,11 +291,11 @@ object Parallel extends ParallelArityFunctions2 { * Like `Bitraverse[A].leftTraverse`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parLeftTraverse[T[_, _]: Bitraverse, M[_], F[_], A, B, C]( + def parLeftTraverse[T[_, _]: Bitraverse, M[_], 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) + )(f: A => M[C])(implicit P: Parallel[M]): M[T[C, B]] = { + val ftcb: P.F[T[C, B]] = + Bitraverse[T].bitraverse(tab)(f.andThen(P.parallel.apply(_)), P.applicative.pure(_))(P.applicative) P.sequential(ftcb) } @@ -294,10 +303,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `Bitraverse[A].leftSequence`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parLeftSequence[T[_, _]: Bitraverse, M[_], F[_], A, B]( + def parLeftSequence[T[_, _]: Bitraverse, M[_], 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) + )(implicit P: Parallel[M]): M[T[A, B]] = { + val ftab: P.F[T[A, B]] = Bitraverse[T].bitraverse(tmab)(P.parallel.apply(_), P.applicative.pure(_))(P.applicative) P.sequential(ftab) } @@ -305,33 +314,33 @@ object Parallel extends ParallelArityFunctions2 { * Like `Applicative[F].ap`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parAp[M[_], F[_], A, B](mf: M[A => B])(ma: M[A])(implicit P: NonEmptyParallel[M, F]): M[B] = + def parAp[M[_], A, B](mf: M[A => B])(ma: M[A])(implicit P: NonEmptyParallel[M]): M[B] = P.sequential(P.apply.ap(P.parallel(mf))(P.parallel(ma))) /** * Like `Applicative[F].product`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parProduct[M[_], F[_], A, B](ma: M[A], mb: M[B])(implicit P: NonEmptyParallel[M, F]): M[(A, B)] = + def parProduct[M[_], A, B](ma: M[A], mb: M[B])(implicit P: NonEmptyParallel[M]): M[(A, B)] = P.sequential(P.apply.product(P.parallel(ma), P.parallel(mb))) /** * Like `Applicative[F].ap2`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parAp2[M[_], F[_], A, B, Z](ff: M[(A, B) => Z])(ma: M[A], mb: M[B])(implicit P: NonEmptyParallel[M, F]): M[Z] = + def parAp2[M[_], A, B, Z](ff: M[(A, B) => Z])(ma: M[A], mb: M[B])(implicit P: NonEmptyParallel[M]): M[Z] = P.sequential( P.apply.ap2(P.parallel(ff))(P.parallel(ma), P.parallel(mb)) ) /** - * Provides an `ApplicativeError[F, E]` instance for any F, that has a `Parallel[M, F]` + * Provides an `ApplicativeError[F, E]` instance for any F, that has a `Parallel.Aux[M, F]` * and a `MonadError[M, E]` instance. * I.e. if you have a type M[_], that supports parallel composition through type F[_], * then you can get `ApplicativeError[F, E]` from `MonadError[M, E]`. */ - def applicativeError[M[_], F[_], E](implicit P: Parallel[M, F], E: MonadError[M, E]): ApplicativeError[F, E] = - P.applicativeError + def applicativeError[M[_], E](implicit P: Parallel[M], E: MonadError[M, E]): ApplicativeError[P.F, E] = + P.applicativeError[E] /** * A Parallel instance for any type `M[_]` that supports parallel composition through itself. @@ -339,7 +348,8 @@ object Parallel extends ParallelArityFunctions2 { * but are required to have an instance of `Parallel` defined, * in which case parallel composition will actually be sequential. */ - def identity[M[_]: Monad]: Parallel[M, M] = new Parallel[M, M] { + def identity[M[_]: Monad]: Parallel.Aux[M, M] = new Parallel[M] { + type F[x] = M[x] val monad: Monad[M] = implicitly[Monad[M]] diff --git a/core/src/main/scala/cats/data/Ior.scala b/core/src/main/scala/cats/data/Ior.scala index 807133fd43..ec6c8d91fc 100644 --- a/core/src/main/scala/cats/data/Ior.scala +++ b/core/src/main/scala/cats/data/Ior.scala @@ -242,8 +242,9 @@ sealed abstract private[data] class IorInstances extends IorInstances0 { } // scalastyle:off cyclomatic.complexity - implicit def catsDataParallelForIor[E](implicit E: Semigroup[E]): Parallel[Ior[E, *], Ior[E, *]] = - new Parallel[Ior[E, *], Ior[E, *]] { + implicit def catsDataParallelForIor[E](implicit E: Semigroup[E]): Parallel.Aux[Ior[E, *], Ior[E, *]] = + new Parallel[Ior[E, *]] { + type F[x] = Ior[E, x] private[this] val identityK: Ior[E, *] ~> Ior[E, *] = FunctionK.id diff --git a/core/src/main/scala/cats/data/IorT.scala b/core/src/main/scala/cats/data/IorT.scala index cca3038fac..514f10726d 100644 --- a/core/src/main/scala/cats/data/IorT.scala +++ b/core/src/main/scala/cats/data/IorT.scala @@ -418,22 +418,24 @@ abstract private[data] class IorTInstances extends IorTInstances1 { implicit def catsDataMonoidForIorT[F[_], A, B](implicit F: Monoid[F[Ior[A, B]]]): Monoid[IorT[F, A, B]] = new IorTMonoid[F, A, B] { val F0: Monoid[F[Ior[A, B]]] = F } - implicit def catsDataParallelForIorTWithParallelEffect[M[_], F[_], E]( - implicit P: Parallel[M, F], + implicit def catsDataParallelForIorTWithParallelEffect[M[_], E]( + implicit P: Parallel[M], E: Semigroup[E] - ): Parallel[IorT[M, E, *], IorT[F, E, *]] { type Dummy } = new Parallel[IorT[M, E, *], IorT[F, E, *]] { + ): Parallel.Aux[IorT[M, E, *], IorT[P.F, E, *]] { type Dummy } = new Parallel[IorT[M, E, *]] { + type F[x] = IorT[P.F, E, x] type Dummy // fix to make this one more specific than the catsDataParallelForIorTWithSequentialEffect, see https://github.com/typelevel/cats/pull/2335#issuecomment-408249775 - val parallel: IorT[M, E, *] ~> IorT[F, E, *] = λ[IorT[M, E, *] ~> IorT[F, E, *]](fm => IorT(P.parallel(fm.value))) - val sequential: IorT[F, E, *] ~> IorT[M, E, *] = - λ[IorT[F, E, *] ~> IorT[M, E, *]](ff => IorT(P.sequential(ff.value))) + val parallel: IorT[M, E, *] ~> IorT[P.F, E, *] = + λ[IorT[M, E, *] ~> IorT[P.F, E, *]](fm => IorT(P.parallel(fm.value))) + val sequential: IorT[P.F, E, *] ~> IorT[M, E, *] = + λ[IorT[P.F, E, *] ~> IorT[M, E, *]](ff => IorT(P.sequential(ff.value))) - private[this] val FA: Applicative[F] = P.applicative + private[this] val FA: Applicative[P.F] = P.applicative private[this] val IorA: Applicative[Ior[E, *]] = Parallel[Ior[E, *], Ior[E, *]].applicative - val applicative: Applicative[IorT[F, E, *]] = new Applicative[IorT[F, E, *]] { - def pure[A](a: A): IorT[F, E, A] = IorT.pure(a)(FA) - def ap[A, B](ff: IorT[F, E, A => B])(fa: IorT[F, E, A]): IorT[F, E, B] = + val applicative: Applicative[IorT[P.F, E, *]] = new Applicative[IorT[P.F, E, *]] { + def pure[A](a: A): IorT[P.F, E, A] = IorT.pure(a)(FA) + def ap[A, B](ff: IorT[P.F, E, A => B])(fa: IorT[P.F, E, A]): IorT[P.F, E, B] = IorT(FA.map2(ff.value, fa.value)((f, a) => IorA.ap(f)(a))) } @@ -463,24 +465,25 @@ abstract private[data] class IorTInstances1 extends IorTInstances2 { val F0: Monad[F] = F } - implicit def catsDataParallelForIorTWithSequentialEffect[F[_], E]( - implicit F: Monad[F], + implicit def catsDataParallelForIorTWithSequentialEffect[F0[_], E]( + implicit F: Monad[F0], E: Semigroup[E] - ): Parallel[IorT[F, E, *], IorT[F, E, *]] = new Parallel[IorT[F, E, *], IorT[F, E, *]] { - private[this] val identityK: IorT[F, E, *] ~> IorT[F, E, *] = FunctionK.id - private[this] val underlyingParallel: Parallel[Ior[E, *], Ior[E, *]] = + ): Parallel.Aux[IorT[F0, E, *], IorT[F0, E, *]] = new Parallel[IorT[F0, E, *]] { + type F[x] = IorT[F0, E, x] + private[this] val identityK: IorT[F0, E, *] ~> IorT[F0, E, *] = FunctionK.id + private[this] val underlyingParallel: Parallel.Aux[Ior[E, *], Ior[E, *]] = Parallel[Ior[E, *], Ior[E, *]] - def parallel: IorT[F, E, *] ~> IorT[F, E, *] = identityK - def sequential: IorT[F, E, *] ~> IorT[F, E, *] = identityK + def parallel: IorT[F0, E, *] ~> IorT[F0, E, *] = identityK + def sequential: IorT[F0, E, *] ~> IorT[F0, E, *] = identityK - val applicative: Applicative[IorT[F, E, *]] = new Applicative[IorT[F, E, *]] { - def pure[A](a: A): IorT[F, E, A] = IorT.pure(a) - def ap[A, B](ff: IorT[F, E, A => B])(fa: IorT[F, E, A]): IorT[F, E, B] = - IorT(F.map2(ff.value, fa.value)((f, a) => underlyingParallel.applicative.ap(f)(a))) + val applicative: Applicative[IorT[F0, E, *]] = new Applicative[IorT[F0, E, *]] { + def pure[A](a: A): IorT[F0, E, A] = IorT.pure(a) + def ap[A, B](ff: IorT[F0, E, A => B])(fa: IorT[F0, E, A]): IorT[F0, E, B] = + IorT(F.map2(ff.value, fa.value)((f, a) => underlyingParallel.applicative.ap[A, B](f)(a))) } - lazy val monad: Monad[IorT[F, E, *]] = Monad[IorT[F, E, *]] + lazy val monad: Monad[IorT[F0, E, *]] = Monad[IorT[F0, E, *]] } } diff --git a/core/src/main/scala/cats/data/Kleisli.scala b/core/src/main/scala/cats/data/Kleisli.scala index cd063d2dcf..c3448d4701 100644 --- a/core/src/main/scala/cats/data/Kleisli.scala +++ b/core/src/main/scala/cats/data/Kleisli.scala @@ -368,19 +368,19 @@ sealed abstract private[data] class KleisliInstances1 extends KleisliInstances2 implicit def catsDataMonadForKleisli[F[_], A](implicit M: Monad[F]): Monad[Kleisli[F, A, *]] = new KleisliMonad[F, A] { def F: Monad[F] = M } - implicit def catsDataParallelForKleisli[F[_], M[_], A]( - implicit P: Parallel[M, F] - ): Parallel[Kleisli[M, A, *], Kleisli[F, A, *]] = new Parallel[Kleisli[M, A, *], Kleisli[F, A, *]] { - implicit val appF = P.applicative - implicit val monadM = P.monad - def applicative: Applicative[Kleisli[F, A, *]] = catsDataApplicativeForKleisli + implicit def catsDataParallelForKleisli[M[_], A]( + implicit P: Parallel[M] + ): Parallel.Aux[Kleisli[M, A, *], Kleisli[P.F, A, *]] = new Parallel[Kleisli[M, A, *]] { + type F[x] = Kleisli[P.F, A, x] + implicit val monadM: Monad[M] = P.monad + def applicative: Applicative[Kleisli[P.F, A, *]] = catsDataApplicativeForKleisli(P.applicative) def monad: Monad[Kleisli[M, A, *]] = catsDataMonadForKleisli - def sequential: Kleisli[F, A, *] ~> Kleisli[M, A, *] = - λ[Kleisli[F, A, *] ~> Kleisli[M, A, *]](_.mapK(P.sequential)) + def sequential: Kleisli[P.F, A, *] ~> Kleisli[M, A, *] = + λ[Kleisli[P.F, A, *] ~> Kleisli[M, A, *]](_.mapK(P.sequential)) - def parallel: Kleisli[M, A, *] ~> Kleisli[F, A, *] = - λ[Kleisli[M, A, *] ~> Kleisli[F, A, *]](_.mapK(P.parallel)) + def parallel: Kleisli[M, A, *] ~> Kleisli[P.F, A, *] = + λ[Kleisli[M, A, *] ~> Kleisli[P.F, A, *]](_.mapK(P.parallel)) } implicit def catsDataContravariantForKleisli[F[_], C]: Contravariant[Kleisli[F, *, C]] = diff --git a/core/src/main/scala/cats/data/NonEmptyList.scala b/core/src/main/scala/cats/data/NonEmptyList.scala index 2e3deee961..0748b1a8cc 100644 --- a/core/src/main/scala/cats/data/NonEmptyList.scala +++ b/core/src/main/scala/cats/data/NonEmptyList.scala @@ -627,8 +627,9 @@ sealed abstract private[data] class NonEmptyListInstances extends NonEmptyListIn val A0 = A } - implicit def catsDataNonEmptyParallelForNonEmptyList[A]: NonEmptyParallel[NonEmptyList, ZipNonEmptyList] = - new NonEmptyParallel[NonEmptyList, ZipNonEmptyList] { + implicit def catsDataNonEmptyParallelForNonEmptyList[A]: NonEmptyParallel.Aux[NonEmptyList, ZipNonEmptyList] = + new NonEmptyParallel[NonEmptyList] { + type F[x] = ZipNonEmptyList[x] def flatMap: FlatMap[NonEmptyList] = NonEmptyList.catsDataInstancesForNonEmptyList diff --git a/core/src/main/scala/cats/data/NonEmptyVector.scala b/core/src/main/scala/cats/data/NonEmptyVector.scala index c7e5933f61..2e8b5e9f60 100644 --- a/core/src/main/scala/cats/data/NonEmptyVector.scala +++ b/core/src/main/scala/cats/data/NonEmptyVector.scala @@ -371,8 +371,9 @@ sealed abstract private[data] class NonEmptyVectorInstances { implicit def catsDataSemigroupForNonEmptyVector[A]: Semigroup[NonEmptyVector[A]] = catsDataInstancesForNonEmptyVector.algebra - implicit def catsDataParallelForNonEmptyVector: NonEmptyParallel[NonEmptyVector, ZipNonEmptyVector] = - new NonEmptyParallel[NonEmptyVector, ZipNonEmptyVector] { + implicit def catsDataParallelForNonEmptyVector: NonEmptyParallel.Aux[NonEmptyVector, ZipNonEmptyVector] = + new NonEmptyParallel[NonEmptyVector] { + type F[x] = ZipNonEmptyVector[x] def apply: Apply[ZipNonEmptyVector] = ZipNonEmptyVector.catsDataCommutativeApplyForZipNonEmptyVector def flatMap: FlatMap[NonEmptyVector] = NonEmptyVector.catsDataInstancesForNonEmptyVector diff --git a/core/src/main/scala/cats/data/OneAnd.scala b/core/src/main/scala/cats/data/OneAnd.scala index 8d775b652a..92260e035c 100644 --- a/core/src/main/scala/cats/data/OneAnd.scala +++ b/core/src/main/scala/cats/data/OneAnd.scala @@ -105,19 +105,20 @@ final case class OneAnd[F[_], A](head: A, tail: F[A]) { @suppressUnusedImportWarningForScalaVersionSpecific sealed abstract private[data] class OneAndInstances extends OneAndLowPriority0 { - implicit def catsDataParallelForOneAnd[A, M[_]: Alternative, F[_]: Alternative]( - implicit P: Parallel[M, F] - ): Parallel[OneAnd[M, *], OneAnd[F, *]] = - new Parallel[OneAnd[M, *], OneAnd[F, *]] { + implicit def catsDataParallelForOneAnd[A, M[_]: Alternative, F0[_]: Alternative]( + implicit P: Parallel.Aux[M, F0] + ): Parallel.Aux[OneAnd[M, *], OneAnd[F0, *]] = + new Parallel[OneAnd[M, *]] { + type F[x] = OneAnd[F0, x] def monad: Monad[OneAnd[M, *]] = catsDataMonadForOneAnd(P.monad, Alternative[M]) - def applicative: Applicative[OneAnd[F, *]] = catsDataApplicativeForOneAnd(Alternative[F]) + def applicative: Applicative[OneAnd[F0, *]] = catsDataApplicativeForOneAnd(Alternative[F0]) - def sequential: OneAnd[F, *] ~> OneAnd[M, *] = - λ[OneAnd[F, *] ~> OneAnd[M, *]](ofa => OneAnd(ofa.head, P.sequential(ofa.tail))) + def sequential: OneAnd[F0, *] ~> OneAnd[M, *] = + λ[OneAnd[F0, *] ~> OneAnd[M, *]](ofa => OneAnd(ofa.head, P.sequential(ofa.tail))) - def parallel: OneAnd[M, *] ~> OneAnd[F, *] = - λ[OneAnd[M, *] ~> OneAnd[F, *]](ofa => OneAnd(ofa.head, P.parallel(ofa.tail))) + def parallel: OneAnd[M, *] ~> OneAnd[F0, *] = + λ[OneAnd[M, *] ~> OneAnd[F0, *]](ofa => OneAnd(ofa.head, P.parallel(ofa.tail))) } diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index 2bc538d440..c61416fdd6 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -152,20 +152,20 @@ sealed abstract private[data] class WriterTInstances1 extends WriterTInstances2 implicit val L0: Monoid[L] = L } - implicit def catsDataParallelForWriterT[F[_], M[_], L: Monoid]( - implicit P: Parallel[M, F] - ): Parallel[WriterT[M, L, *], WriterT[F, L, *]] = new Parallel[WriterT[M, L, *], WriterT[F, L, *]] { - implicit val appF = P.applicative - implicit val monadM = P.monad + implicit def catsDataParallelForWriterT[M[_], L: Monoid]( + implicit P: Parallel[M] + ): Parallel.Aux[WriterT[M, L, *], WriterT[P.F, L, *]] = new Parallel[WriterT[M, L, *]] { + type F[x] = WriterT[P.F, L, x] + implicit val monadM: Monad[M] = P.monad - def applicative: Applicative[WriterT[F, L, *]] = catsDataApplicativeForWriterT + def applicative: Applicative[WriterT[P.F, L, *]] = catsDataApplicativeForWriterT(P.applicative, Monoid[L]) def monad: Monad[WriterT[M, L, *]] = catsDataMonadForWriterT - def sequential: WriterT[F, L, *] ~> WriterT[M, L, *] = - λ[WriterT[F, L, *] ~> WriterT[M, L, *]](wfl => WriterT(P.sequential(wfl.run))) + def sequential: WriterT[P.F, L, *] ~> WriterT[M, L, *] = + λ[WriterT[P.F, L, *] ~> WriterT[M, L, *]](wfl => WriterT(P.sequential(wfl.run))) - def parallel: WriterT[M, L, *] ~> WriterT[F, L, *] = - λ[WriterT[M, L, *] ~> WriterT[F, L, *]](wml => WriterT(P.parallel(wml.run))) + def parallel: WriterT[M, L, *] ~> WriterT[P.F, L, *] = + λ[WriterT[M, L, *] ~> WriterT[P.F, L, *]](wml => WriterT(P.parallel(wml.run))) } implicit def catsDataEqForWriterTId[L: Eq, V: Eq]: Eq[WriterT[Id, L, V]] = diff --git a/core/src/main/scala/cats/instances/parallel.scala b/core/src/main/scala/cats/instances/parallel.scala index 8c9017a100..df420e1e47 100644 --- a/core/src/main/scala/cats/instances/parallel.scala +++ b/core/src/main/scala/cats/instances/parallel.scala @@ -8,8 +8,9 @@ import cats.{~>, Applicative, Monad, Parallel} private[instances] trait ParallelInstances1 { implicit def catsParallelForEitherTNestedValidated[M[_]: Monad, E: Semigroup] - : Parallel[EitherT[M, E, *], Nested[M, Validated[E, *], *]] = - new Parallel[EitherT[M, E, *], Nested[M, Validated[E, *], *]] { + : Parallel.Aux[EitherT[M, E, *], Nested[M, Validated[E, *], *]] = + new Parallel[EitherT[M, E, *]] { + type F[x] = Nested[M, Validated[E, *], x] implicit val appValidated: Applicative[Validated[E, *]] = Validated.catsDataApplicativeErrorForValidated implicit val monadEither: Monad[Either[E, *]] = cats.instances.either.catsStdInstancesForEither diff --git a/core/src/main/scala/cats/package.scala b/core/src/main/scala/cats/package.scala index b42624ef2e..bfba3d35b6 100644 --- a/core/src/main/scala/cats/package.scala +++ b/core/src/main/scala/cats/package.scala @@ -90,7 +90,7 @@ package object cats { override def index[A](f: Id[A]): Unit => A = (_: Unit) => f } - implicit val catsParallelForId: Parallel[Id, Id] = Parallel.identity + implicit val catsParallelForId: Parallel.Aux[Id, Id] = Parallel.identity type Eq[A] = cats.kernel.Eq[A] type PartialOrder[A] = cats.kernel.PartialOrder[A] diff --git a/core/src/main/scala/cats/syntax/parallel.scala b/core/src/main/scala/cats/syntax/parallel.scala index b56f5844d3..f21e4982bf 100644 --- a/core/src/main/scala/cats/syntax/parallel.scala +++ b/core/src/main/scala/cats/syntax/parallel.scala @@ -80,40 +80,40 @@ trait ParallelUnorderedTraverseSyntax { } 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]] = + def parTraverse[M[_]: Monad, B](f: A => M[B])(implicit T: Traverse[T], P: Parallel[M]): M[T[B]] = Parallel.parTraverse(ta)(f) } final class ParallelTraversable_Ops[T[_], A](private val ta: T[A]) extends AnyVal { - def parTraverse_[M[_], F[_], B](f: A => M[B])(implicit T: Foldable[T], P: Parallel[M, F]): M[Unit] = + def parTraverse_[M[_], B](f: A => M[B])(implicit T: Foldable[T], P: Parallel[M]): M[Unit] = Parallel.parTraverse_(ta)(f) } final class ParallelFlatTraversableOps[T[_], A](private val ta: T[A]) extends AnyVal { - def parFlatTraverse[M[_]: Monad, F[_], B]( + def parFlatTraverse[M[_]: Monad, B]( f: A => M[T[B]] - )(implicit T0: Traverse[T], T1: FlatMap[T], P: Parallel[M, F]): M[T[B]] = + )(implicit T0: Traverse[T], T1: FlatMap[T], P: Parallel[M]): M[T[B]] = Parallel.parFlatTraverse(ta)(f) } final class ParallelSequenceOps[T[_], M[_], A](private val tma: T[M[A]]) extends AnyVal { - def parSequence[F[_]](implicit M: Monad[M], T: Traverse[T], P: Parallel[M, F]): M[T[A]] = + def parSequence(implicit M: Monad[M], T: Traverse[T], P: Parallel[M]): M[T[A]] = Parallel.parSequence(tma) } final class ParallelSequence_Ops[T[_], M[_], A](private val tma: T[M[A]]) extends AnyVal { - def parSequence_[F[_]](implicit T: Foldable[T], P: Parallel[M, F]): M[Unit] = + def parSequence_(implicit T: Foldable[T], P: Parallel[M]): M[Unit] = Parallel.parSequence_(tma) } final class ParallelFlatSequenceOps[T[_], M[_], A](private val tmta: T[M[T[A]]]) extends AnyVal { - def parFlatSequence[F[_]](implicit M: Monad[M], T0: Traverse[T], T1: FlatMap[T], P: Parallel[M, F]): M[T[A]] = + def parFlatSequence(implicit M: Monad[M], T0: Traverse[T], T1: FlatMap[T], P: Parallel[M]): M[T[A]] = Parallel.parFlatSequence(tmta) } final class ParallelUnorderedSequenceOps[T[_], M[_], A](private val tmta: T[M[A]]) extends AnyVal { - def parUnorderedSequence[F[_]](implicit P: Parallel[M, F], + def parUnorderedSequence[F[_]](implicit P: Parallel.Aux[M, F], F: CommutativeApplicative[F], Tutraverse: UnorderedTraverse[T]): M[T[A]] = Parallel.parUnorderedSequence(tmta) @@ -122,12 +122,12 @@ final class ParallelUnorderedSequenceOps[T[_], M[_], A](private val tmta: T[M[A] final class ParallelUnorderedTraverseOps[T[_], A](private val ta: T[A]) extends AnyVal { def parUnorderedTraverse[M[_], F[_], B]( f: A => M[B] - )(implicit P: Parallel[M, F], F: CommutativeApplicative[F], Tutraverse: UnorderedTraverse[T]): M[T[B]] = + )(implicit P: Parallel.Aux[M, F], F: CommutativeApplicative[F], Tutraverse: UnorderedTraverse[T]): M[T[B]] = Parallel.parUnorderedTraverse(ta)(f) def parUnorderedFlatTraverse[M[_], F[_], B]( f: A => M[T[B]] - )(implicit P: Parallel[M, F], + )(implicit P: Parallel.Aux[M, F], F: CommutativeApplicative[F], Tflatmap: FlatMap[T], Tutraverse: UnorderedTraverse[T]): M[T[B]] = @@ -135,7 +135,7 @@ final class ParallelUnorderedTraverseOps[T[_], A](private val ta: T[A]) extends } final class ParallelUnorderedFlatSequenceOps[T[_], M[_], A](private val tmta: T[M[T[A]]]) extends AnyVal { - def parUnorderedFlatSequence[F[_]](implicit P: Parallel[M, F], + def parUnorderedFlatSequence[F[_]](implicit P: Parallel.Aux[M, F], Tflatmap: FlatMap[T], F: CommutativeApplicative[F], Tutraverse: UnorderedTraverse[T]): M[T[A]] = @@ -144,36 +144,35 @@ final class ParallelUnorderedFlatSequenceOps[T[_], M[_], A](private val tmta: T[ final class ParallelApOps[M[_], A](private val ma: M[A]) extends AnyVal { - def &>[F[_], B](mb: M[B])(implicit P: Parallel[M, F]): M[B] = + def &>[B](mb: M[B])(implicit P: Parallel[M]): M[B] = P.parProductR(ma)(mb) - def <&[F[_], B](mb: M[B])(implicit P: Parallel[M, F]): M[A] = + def <&[B](mb: M[B])(implicit P: Parallel[M]): M[A] = P.parProductL(ma)(mb) } final class ParallelApplyOps[M[_], A, B](private val mab: M[A => B]) extends AnyVal { - def <&>[F[_]](ma: M[A])(implicit P: Parallel[M, F]): M[B] = - Parallel.parAp(mab)(ma) + def <&>(ma: M[A])(implicit P: Parallel[M]): M[B] = + Parallel.parAp(mab)(ma)(P) } 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]] = + def parBitraverse[M[_], C, D](f: A => M[C], g: B => M[D])(implicit T: Bitraverse[T], P: Parallel[M]): 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]] = + def parBisequence(implicit T: Bitraverse[T], P: Parallel[M]): 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]] = + def parLeftTraverse[M[_], C](f: A => M[C])(implicit T: Bitraverse[T], P: Parallel[M]): 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]] = + def parLeftSequence(implicit T: Bitraverse[T], P: Parallel[M]): M[T[A, B]] = Parallel.parLeftSequence(tmab) } diff --git a/docs/src/main/tut/faq.md b/docs/src/main/tut/faq.md index 390f59fda0..c6959c8901 100644 --- a/docs/src/main/tut/faq.md +++ b/docs/src/main/tut/faq.md @@ -239,8 +239,8 @@ All other symbols can be imported with `import cats.implicits._` | `F ~> G` | natural transformation | | `FunctionK[F[_], G[_]]` | `FunctionK` alias | | `F :<: G` | injectK | | `InjectK[F[_], G[_]]` | `InjectK` alias | | `F :≺: G` | injectK | | `InjectK[F[_], G[_]]` | `InjectK` alias | -| `fa &> fb` | parallel product right | | `Parallel[M[_], F[_]]` | `parProductR[A, B](ma: M[A])(mb: M[B]): M[B]` | -| `fa <& fb` | parallel product left | | `Parallel[M[_], F[_]]` | `parProductL[A, B](ma: M[A])(mb: M[B]): M[A]` | +| `fa &> fb` | parallel product right | | `Parallel[M[_]]` | `parProductR[A, B](ma: M[A])(mb: M[B]): M[B]` | +| `fa <& fb` | parallel product left | | `Parallel[M[_]]` | `parProductL[A, B](ma: M[A])(mb: M[B]): M[A]` | | `⊥` | bottom | | N/A | `Nothing` | | `⊤` | top | | N/A | `Any` | | `fa << fb` (Deprecated) | product left | | `FlatMap[F[_]]` | `productL(fa: F[A])(fb: F[B]): F[A]` | diff --git a/docs/src/main/tut/typeclasses/parallel.md b/docs/src/main/tut/typeclasses/parallel.md index e28aeb4865..d2501c7e9d 100644 --- a/docs/src/main/tut/typeclasses/parallel.md +++ b/docs/src/main/tut/typeclasses/parallel.md @@ -64,7 +64,9 @@ To mitigate this pain, Cats introduces a type class `Parallel` that abstracts ov It is simply defined in terms of conversion functions between the two data types: ```scala -trait Parallel[M[_], F[_]] { +trait Parallel[M[_]] { + type F[_] + def sequential: F ~> M def parallel: M ~> F diff --git a/laws/src/main/scala/cats/laws/NonEmptyParallelLaws.scala b/laws/src/main/scala/cats/laws/NonEmptyParallelLaws.scala index 23d721d4de..96deeb8df0 100644 --- a/laws/src/main/scala/cats/laws/NonEmptyParallelLaws.scala +++ b/laws/src/main/scala/cats/laws/NonEmptyParallelLaws.scala @@ -5,7 +5,7 @@ package laws * Laws that must be obeyed by any `cats.NonEmptyParallel`. */ trait NonEmptyParallelLaws[M[_], F[_]] { - def P: NonEmptyParallel[M, F] + def P: NonEmptyParallel.Aux[M, F] def parallelRoundTrip[A](ma: M[A]): IsEq[M[A]] = P.sequential(P.parallel(ma)) <-> ma @@ -18,6 +18,6 @@ trait NonEmptyParallelLaws[M[_], F[_]] { } object NonEmptyParallelLaws { - def apply[M[_], F[_]](implicit ev: NonEmptyParallel[M, F]): NonEmptyParallelLaws[M, F] = - new NonEmptyParallelLaws[M, F] { def P: NonEmptyParallel[M, F] = ev } + def apply[M[_], F[_]](implicit ev: NonEmptyParallel.Aux[M, F]): NonEmptyParallelLaws[M, F] = + new NonEmptyParallelLaws[M, F] { def P: NonEmptyParallel.Aux[M, F] = ev } } diff --git a/laws/src/main/scala/cats/laws/ParallelLaws.scala b/laws/src/main/scala/cats/laws/ParallelLaws.scala index 9573f48d12..892ca79eae 100644 --- a/laws/src/main/scala/cats/laws/ParallelLaws.scala +++ b/laws/src/main/scala/cats/laws/ParallelLaws.scala @@ -5,13 +5,13 @@ package laws * Laws that must be obeyed by any `cats.Parallel`. */ trait ParallelLaws[M[_], F[_]] extends NonEmptyParallelLaws[M, F] { - def P: Parallel[M, F] + def P: Parallel.Aux[M, F] def isomorphicPure[A](a: A): IsEq[F[A]] = P.applicative.pure(a) <-> P.parallel(P.monad.pure(a)) } object ParallelLaws { - def apply[M[_], F[_]](implicit ev: Parallel[M, F]): ParallelLaws[M, F] = - new ParallelLaws[M, F] { def P: Parallel[M, F] = ev } + def apply[M[_], F[_]](implicit ev: Parallel.Aux[M, F]): ParallelLaws[M, F] = + new ParallelLaws[M, F] { def P: Parallel.Aux[M, F] = ev } } diff --git a/laws/src/main/scala/cats/laws/discipline/NonEmptyParallelTests.scala b/laws/src/main/scala/cats/laws/discipline/NonEmptyParallelTests.scala index 0dc268cb7b..64b14b8c3f 100644 --- a/laws/src/main/scala/cats/laws/discipline/NonEmptyParallelTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/NonEmptyParallelTests.scala @@ -27,6 +27,6 @@ trait NonEmptyParallelTests[M[_], F[_]] extends Laws { } object NonEmptyParallelTests { - def apply[M[_], F[_]](implicit ev: NonEmptyParallel[M, F]): NonEmptyParallelTests[M, F] = + def apply[M[_], F[_]](implicit ev: NonEmptyParallel.Aux[M, F]): NonEmptyParallelTests[M, F] = new NonEmptyParallelTests[M, F] { val laws: NonEmptyParallelLaws[M, F] = NonEmptyParallelLaws[M, F] } } diff --git a/laws/src/main/scala/cats/laws/discipline/ParallelTests.scala b/laws/src/main/scala/cats/laws/discipline/ParallelTests.scala index 4b1cba0b9d..b5b394adc7 100644 --- a/laws/src/main/scala/cats/laws/discipline/ParallelTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ParallelTests.scala @@ -24,6 +24,6 @@ trait ParallelTests[M[_], F[_]] extends NonEmptyParallelTests[M, F] { } object ParallelTests { - def apply[M[_], F[_]](implicit ev: Parallel[M, F]): ParallelTests[M, F] = + def apply[M[_], F[_]](implicit ev: Parallel.Aux[M, F]): ParallelTests[M, F] = new ParallelTests[M, F] { val laws: ParallelLaws[M, F] = ParallelLaws[M, F] } } diff --git a/project/Boilerplate.scala b/project/Boilerplate.scala index 4a0483ffa3..6105f334e8 100644 --- a/project/Boilerplate.scala +++ b/project/Boilerplate.scala @@ -270,7 +270,7 @@ object Boilerplate { | */ |trait ParallelArityFunctions { - /** @group ParMapArity */ - - def parMap$arity[M[_], F[_], ${`A..N`}, Z]($fparams)(f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = + - def parMap$arity[M[_], ${`A..N`}, Z]($fparams)(f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M]): M[Z] = - p.flatMap.map(${nestedExpansion.products}) { case ${nestedExpansion.`(a..n)`} => f(${`a..n`}) } |} """ @@ -303,7 +303,7 @@ object Boilerplate { | */ |abstract class ParallelArityFunctions2 extends ParallelArityFunctions { - /** @group ParTupleArity */ - - def parTuple$arity[M[_], F[_], ${`A..N`}]($fparams)(implicit p: NonEmptyParallel[M, F]): M[(${`A..N`})] = + - def parTuple$arity[M[_], ${`A..N`}]($fparams)(implicit p: NonEmptyParallel[M]): M[(${`A..N`})] = - p.flatMap.map(${nestedExpansion.products}) { case ${nestedExpansion.`(a..n)`} => (${`a..n`}) } |} """ @@ -398,14 +398,14 @@ object Boilerplate { val parMap = if (arity == 1) - s"def parMap[F[_], Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = p.flatMap.map($tupleArgs)(f)" + s"def parMap[Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M]): M[Z] = p.flatMap.map($tupleArgs)(f)" else - s"def parMapN[F[_], Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = Parallel.parMap$arity($tupleArgs)(f)" + s"def parMapN[Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M]): M[Z] = Parallel.parMap$arity($tupleArgs)(f)" val parTupled = if (arity == 1) "" else - s"def parTupled[F[_]](implicit p: NonEmptyParallel[M, F]): M[(${`A..N`})] = Parallel.parTuple$arity($tupleArgs)" + s"def parTupled(implicit p: NonEmptyParallel[M]): M[(${`A..N`})] = Parallel.parTuple$arity($tupleArgs)" block""" |package cats diff --git a/tests/src/test/scala/cats/tests/ParallelSuite.scala b/tests/src/test/scala/cats/tests/ParallelSuite.scala index ef6cc4f4ff..de4d21e511 100644 --- a/tests/src/test/scala/cats/tests/ParallelSuite.scala +++ b/tests/src/test/scala/cats/tests/ParallelSuite.scala @@ -386,7 +386,8 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest with Sc def flatMap[A, B](fa: Effect[A])(f: A => Effect[B]): Effect[B] = throw Marker("sequential") def tailRecM[A, B](a: A)(f: A => Effect[Either[A, B]]): Effect[B] = ??? } - val parallelInstance: Parallel[Effect, Effect] = new Parallel[Effect, Effect] { + val parallelInstance: Parallel.Aux[Effect, Effect] = new Parallel[Effect] { + type F[x] = Effect[x] def parallel: Effect ~> Effect = arrow.FunctionK.id def sequential: Effect ~> Effect = arrow.FunctionK.id @@ -490,7 +491,7 @@ trait ApplicativeErrorForEitherTest extends AnyFunSuiteLike with Discipline { implicit def eqV[A: Eq, B: Eq]: Eq[Validated[A, B]] = cats.data.Validated.catsDataEqForValidated { - implicit val parVal = Parallel.applicativeError[Either[String, *], Validated[String, *], String] + implicit val parVal = Parallel.applicativeError[Either[String, *], String] checkAll("ApplicativeError[Validated[String, Int]]", ApplicativeErrorTests[Validated[String, *], String].applicativeError[Int, Int, Int]) diff --git a/tests/src/test/scala/cats/tests/SyntaxSuite.scala b/tests/src/test/scala/cats/tests/SyntaxSuite.scala index a346adb52b..5374ea4af5 100644 --- a/tests/src/test/scala/cats/tests/SyntaxSuite.scala +++ b/tests/src/test/scala/cats/tests/SyntaxSuite.scala @@ -183,7 +183,7 @@ object SyntaxSuite val gunit: G[F[A]] = fga.nonEmptySequence } - def testParallel[M[_]: Monad, F[_], T[_]: Traverse, A, B](implicit P: Parallel[M, F]): Unit = { + def testParallel[M[_]: Monad, F[_], T[_]: Traverse, A, B](implicit P: Parallel.Aux[M, F]): Unit = { val ta = mock[T[A]] val f = mock[A => M[B]] val mtb = ta.parTraverse(f) @@ -202,7 +202,7 @@ object SyntaxSuite } def testParallelUnorderedTraverse[M[_]: Monad, F[_]: CommutativeApplicative, T[_]: UnorderedTraverse: FlatMap, A, B]( - implicit P: Parallel[M, F] + implicit P: Parallel.Aux[M, F] ): Unit = { val ta = mock[T[A]] val f = mock[A => M[B]] @@ -218,7 +218,7 @@ object SyntaxSuite val mtb2 = ta.parUnorderedFlatTraverse(g) } - def testParallelFlat[M[_]: Monad, F[_], T[_]: Traverse: FlatMap, A, B](implicit P: Parallel[M, F]): Unit = { + def testParallelFlat[M[_]: Monad, F[_], T[_]: Traverse: FlatMap, A, B](implicit P: Parallel.Aux[M, F]): Unit = { val ta = mock[T[A]] val f = mock[A => M[T[B]]] val mtb = ta.parFlatTraverse(f) @@ -227,7 +227,7 @@ object SyntaxSuite val mta = tmta.parFlatSequence } - def testParallelTuple[M[_]: Monad, F[_], A, B, C, Z](implicit P: NonEmptyParallel[M, F]) = { + def testParallelTuple[M[_]: Monad, F[_], A, B, C, Z](implicit P: NonEmptyParallel.Aux[M, F]) = { val tfabc = mock[(M[A], M[B], M[C])] val fa = mock[M[A]] val fb = mock[M[B]] @@ -238,7 +238,7 @@ object SyntaxSuite (fa, fb, fc).parMapN(f) } - def testParallelBi[M[_], F[_], T[_, _]: Bitraverse, A, B, C, D](implicit P: Parallel[M, F]): Unit = { + def testParallelBi[M[_], F[_], T[_, _]: Bitraverse, A, B, C, D](implicit P: Parallel.Aux[M, F]): Unit = { val tab = mock[T[A, B]] val f = mock[A => M[C]] val g = mock[B => M[D]]