Similar to Either#combine
but mapped over an F
context.
Similar to Either#combine
but mapped over an F
context.
Examples:
scala> import cats.data.EitherT scala> import cats.implicits._ scala> val l1: EitherT[Option, String, Int] = EitherT.left(Some("error 1")) scala> val l2: EitherT[Option, String, Int] = EitherT.left(Some("error 2")) scala> val r3: EitherT[Option, String, Int] = EitherT.right(Some(3)) scala> val r4: EitherT[Option, String, Int] = EitherT.right(Some(4)) scala> val noneEitherT: EitherT[Option, String, Int] = EitherT.left(None) scala> l1 combine l2 res0: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) scala> l1 combine r3 res1: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) scala> r3 combine l1 res2: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) scala> r3 combine r4 res3: EitherT[Option, String, Int] = EitherT(Some(Right(7))) scala> l1 combine noneEitherT res4: EitherT[Option, String, Int] = EitherT(None) scala> noneEitherT combine l1 res5: EitherT[Option, String, Int] = EitherT(None) scala> r3 combine noneEitherT res6: EitherT[Option, String, Int] = EitherT(None) scala> noneEitherT combine r4 res7: EitherT[Option, String, Int] = EitherT(None)
Transform this EitherT[F, A, B]
into a Nested[F, Either[A, ?], B]
.
Transform this EitherT[F, A, B]
into a Nested[F, Either[A, ?], B]
.
An example where toNested
can be used, is to get the Apply.ap
function with the
behavior from the composed Apply
instances from F
and Either[A, ?]
, which is
inconsistent with the behavior of the ap
from Monad
of EitherT
.
scala> import cats.data.{Nested, EitherT} scala> import cats.implicits._ scala> val ff: EitherT[List, String, Int => String] = | EitherT(List(Either.right(_.toString), Either.left("error"))) scala> val fa: EitherT[List, String, Int] = | EitherT(List(Either.right(1), Either.right(2))) scala> type ErrorOr[A] = Either[String, A] scala> type ListErrorOr[A] = Nested[List, ErrorOr, A] scala> ff.ap(fa) res0: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error))) scala> EitherT((ff.toNested: ListErrorOr[Int => String]).ap(fa.toNested: ListErrorOr[Int]).value) res1: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error), Left(error)))
Note that we need the ErrorOr
type alias above because otherwise we can't use the
syntax function ap
on Nested[List, Either[A, ?], B]
. This won't be needed after cats has
decided how to handle the SI-2712 fix.
Run this value as a Validated
against the function and convert it back to an EitherT
.
Run this value as a Validated
against the function and convert it back to an EitherT
.
The Applicative instance for EitherT
"fails fast" - it is often useful to "momentarily" have
it accumulate errors instead, which is what the Validated
data type gives us.
Example:
scala> import cats.implicits._ scala> type Error = String scala> val v1: Validated[NonEmptyList[Error], Int] = Validated.Invalid(NonEmptyList.of("error 1")) scala> val v2: Validated[NonEmptyList[Error], Int] = Validated.Invalid(NonEmptyList.of("error 2")) scala> val eithert: EitherT[Option, Error, Int] = EitherT(Some(Either.left("error 3"))) scala> eithert.withValidated { v3 => (v1 |@| v2 |@| v3.leftMap(NonEmptyList.of(_))).map{ case (i, j, k) => i + j + k } } res0: EitherT[Option, NonEmptyList[Error], Int] = EitherT(Some(Left(NonEmptyList(error 1, error 2, error 3))))
Transformer for
Either
, allowing the effect of an arbitrary type constructorF
to be combined with the fail-fast effect ofEither
.EitherT[F, A, B]
wraps a value of typeF[Either[A, B]]
. AnF[C]
can be lifted in toEitherT[F, A, C]
viaEitherT.right
, and lifted in to aEitherT[F, C, B]
viaEitherT.left
.