Skip to content

Commit

Permalink
Merge pull request #3033 from travisbrown/fix/3032
Browse files Browse the repository at this point in the history
Move Parallel instances for EitherT and OptionT into implicit scope
  • Loading branch information
travisbrown authored Sep 7, 2019
2 parents e87c56e + 2dfc1e0 commit bfc264e
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package instances
import cats.data._
import cats.kernel.Semigroup
import cats.syntax.either._
import cats.{~>, Applicative, Apply, FlatMap, Functor, Monad, NonEmptyParallel, Parallel}
import cats.{~>, Applicative, Apply, FlatMap, Monad, NonEmptyParallel, Parallel}

trait ParallelInstances extends ParallelInstances1 {
implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel.Aux[Either[E, *], Validated[E, *]] =
Expand All @@ -21,24 +21,10 @@ trait ParallelInstances extends ParallelInstances1 {
λ[Either[E, *] ~> Validated[E, *]](_.toValidated)
}

implicit def catsParallelForOptionTNestedOption[M[_]](
@deprecated("Use OptionT.catsDataParallelForOptionT", "2.0.0")
private[instances] 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 monadM: Monad[M] = P.monad

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[P.F, Option, *] ~> OptionT[M, *] =
λ[Nested[P.F, Option, *] ~> OptionT[M, *]](nested => OptionT(P.sequential(nested.value)))

def parallel: OptionT[M, *] ~> Nested[P.F, Option, *] =
λ[OptionT[M, *] ~> Nested[P.F, Option, *]](optT => Nested(P.parallel(optT.value)))
}
): Parallel.Aux[OptionT[M, *], Nested[P.F, Option, *]] = OptionT.catsDataParallelForOptionT[M]

implicit def catsStdNonEmptyParallelForZipList[A]: NonEmptyParallel.Aux[List, ZipList] =
new NonEmptyParallel[List] {
Expand Down Expand Up @@ -82,30 +68,9 @@ trait ParallelInstances extends ParallelInstances1 {
λ[Stream ~> ZipStream](v => new ZipStream(v))
}

implicit def catsParallelForEitherTNestedParallelValidated[M[_], E: Semigroup](
@deprecated("Use EitherT.catsDataParallelForEitherTWithParallelEffect", "2.0.0")
private[instances] 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 monadM: Monad[M] = P.monad
implicit val monadEither: Monad[Either[E, *]] = cats.instances.either.catsStdInstancesForEither

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[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[P.F, Validated[E, *], *] =
λ[EitherT[M, E, *] ~> Nested[P.F, Validated[E, *], *]] { eitherT =>
val fea = P.parallel(eitherT.value)
Nested(P.applicative.map(fea)(_.toValidated))
}
}
EitherT.catsDataParallelForEitherTWithParallelEffect[M, E]
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package instances
import cats.data._
import cats.kernel.Semigroup
import cats.syntax.either._
import cats.{~>, Applicative, Apply, FlatMap, Functor, Monad, NonEmptyParallel, Parallel}
import cats.{~>, Applicative, Apply, FlatMap, Monad, NonEmptyParallel, Parallel}

trait ParallelInstances extends ParallelInstances1 {
implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel.Aux[Either[E, *], Validated[E, *]] =
Expand All @@ -21,24 +21,10 @@ trait ParallelInstances extends ParallelInstances1 {
λ[Either[E, *] ~> Validated[E, *]](_.toValidated)
}

implicit def catsParallelForOptionTNestedOption[M[_]](
@deprecated("Use OptionT.catsDataParallelForOptionT", "2.0.0")
private[instances] 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 monadM: Monad[M] = P.monad

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[P.F, Option, *] ~> OptionT[M, *] =
λ[Nested[P.F, Option, *] ~> OptionT[M, *]](nested => OptionT(P.sequential(nested.value)))

def parallel: OptionT[M, *] ~> Nested[P.F, Option, *] =
λ[OptionT[M, *] ~> Nested[P.F, Option, *]](optT => Nested(P.parallel(optT.value)))
}
): Parallel.Aux[OptionT[M, *], Nested[P.F, Option, *]] = OptionT.catsDataParallelForOptionT[M]

implicit def catsStdNonEmptyParallelForZipList[A]: NonEmptyParallel.Aux[List, ZipList] =
new NonEmptyParallel[List] {
Expand Down Expand Up @@ -97,30 +83,9 @@ trait ParallelInstances extends ParallelInstances1 {
λ[LazyList ~> ZipLazyList](v => new ZipLazyList(v))
}

implicit def catsParallelForEitherTNestedParallelValidated[M[_], E: Semigroup](
@deprecated("Use EitherT.catsDataParallelForEitherTWithParallelEffect", "2.0.0")
private[instances] 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 monadM: Monad[M] = P.monad
implicit val monadEither: Monad[Either[E, *]] = cats.instances.either.catsStdInstancesForEither

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[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[P.F, Validated[E, *], *] =
λ[EitherT[M, E, *] ~> Nested[P.F, Validated[E, *], *]] { eitherT =>
val fea = P.parallel(eitherT.value)
Nested(P.applicative.map(fea)(_.toValidated))
}
}
EitherT.catsDataParallelForEitherTWithParallelEffect[M, E]
}
51 changes: 51 additions & 0 deletions core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,33 @@ abstract private[data] class EitherTInstances extends EitherTInstances1 {
def defer[A](fa: => EitherT[F, L, A]): EitherT[F, L, A] =
EitherT(F.defer(fa.value))
}

implicit def catsDataParallelForEitherTWithParallelEffect[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 monadM: Monad[M] = P.monad
implicit val monadEither: Monad[Either[E, *]] = cats.instances.either.catsStdInstancesForEither

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[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[P.F, Validated[E, *], *] =
λ[EitherT[M, E, *] ~> Nested[P.F, Validated[E, *], *]] { eitherT =>
val fea = P.parallel(eitherT.value)
Nested(P.applicative.map(fea)(_.toValidated))
}
}
}

abstract private[data] class EitherTInstances1 extends EitherTInstances2 {
Expand Down Expand Up @@ -571,6 +598,30 @@ abstract private[data] class EitherTInstances1 extends EitherTInstances2 {
override def ensureOr[A](fa: EitherT[F, L, A])(error: (A) => L)(predicate: (A) => Boolean): EitherT[F, L, A] =
fa.ensureOr(error)(predicate)(F)
}

implicit def catsDataParallelForEitherTWithSequentialEffect[M[_]: Monad, E: Semigroup]
: 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

def applicative: Applicative[Nested[M, Validated[E, *], *]] =
cats.data.Nested.catsDataApplicativeForNested[M, Validated[E, *]]

def monad: Monad[EitherT[M, E, *]] = cats.data.EitherT.catsDataMonadErrorForEitherT

def sequential: Nested[M, Validated[E, *], *] ~> EitherT[M, E, *] =
λ[Nested[M, Validated[E, *], *] ~> EitherT[M, E, *]] { nested =>
EitherT(Monad[M].map(nested.value)(_.toEither))
}

def parallel: EitherT[M, E, *] ~> Nested[M, Validated[E, *], *] =
λ[EitherT[M, E, *] ~> Nested[M, Validated[E, *], *]] { eitherT =>
Nested(Monad[M].map(eitherT.value)(_.toValidated))
}
}
}

abstract private[data] class EitherTInstances2 extends EitherTInstances3 {
Expand Down
19 changes: 19 additions & 0 deletions core/src/main/scala/cats/data/OptionT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,25 @@ sealed abstract private[data] class OptionTInstances extends OptionTInstances0 {
@deprecated("renamed to catsDataTraverseFilterForOptionT", "2.0.0")
def catsDateTraverseFilterForOptionT[F[_]](implicit F0: Traverse[F]): TraverseFilter[OptionT[F, *]] =
catsDataTraverseFilterForOptionT

implicit def catsDataParallelForOptionT[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 monadM: Monad[M] = P.monad

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[P.F, Option, *] ~> OptionT[M, *] =
λ[Nested[P.F, Option, *] ~> OptionT[M, *]](nested => OptionT(P.sequential(nested.value)))

def parallel: OptionT[M, *] ~> Nested[P.F, Option, *] =
λ[OptionT[M, *] ~> Nested[P.F, Option, *]](optT => Nested(P.parallel(optT.value)))
}
}

sealed abstract private[data] class OptionTInstances0 extends OptionTInstances1 {
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/scala/cats/instances/parallel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import cats.syntax.either._
import cats.{~>, Applicative, Monad, Parallel}

private[instances] trait ParallelInstances1 {
implicit def catsParallelForEitherTNestedValidated[M[_]: Monad, E: Semigroup]
@deprecated("Use EitherT.catsDataParallelForEitherTWithSequentialEffect", "2.0.0")
private[instances] def catsParallelForEitherTNestedValidated[M[_]: Monad, E: Semigroup]
: Parallel.Aux[EitherT[M, E, *], Nested[M, Validated[E, *], *]] =
new Parallel[EitherT[M, E, *]] {
type F[x] = Nested[M, Validated[E, *], x]
Expand Down

0 comments on commit bfc264e

Please sign in to comment.