EitherT

final case class EitherT[F[_], A, B](value: F[Either[A, B]])

Transformer for Either, allowing the effect of an arbitrary type constructor F to be combined with the fail-fast effect of Either.

EitherT[F, A, B] wraps a value of type F[Either[A, B]]. An F[C] can be lifted in to EitherT[F, A, C] via EitherT.right, and lifted in to a EitherT[F, C, B] via EitherT.left.

Companion:
object
trait Product
trait Equals
class Object
trait Matchable
class Any

Value members

Concrete methods

def ===(that: EitherT[F, A, B])(implicit eq: Eq[F[Either[A, B]]]): Boolean
def applyAlt[D](ff: EitherT[F, A, B => D])(implicit F: Apply[F]): EitherT[F, A, D]
def biSemiflatMap[C, D](fa: A => F[C], fb: B => F[D])(implicit F: Monad[F]): EitherT[F, C, D]

Combine leftSemiflatMap and semiflatMap together.

Combine leftSemiflatMap and semiflatMap together.

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Left("abc"), Right(123)))
scala> eitherT.biSemiflatMap(string => List(string.length), int => List(int.toFloat))
res0: cats.data.EitherT[List,Int,Float] = EitherT(List(Left(3), Right(123.0)))
def biflatMap[C, D](fa: A => EitherT[F, C, D], fb: B => EitherT[F, C, D])(implicit F: FlatMap[F]): EitherT[F, C, D]
def bimap[C, D](fa: A => C, fb: B => D)(implicit F: Functor[F]): EitherT[F, C, D]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] =
    |   EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> eitherT.bimap(string => string.length, int => int % 100)
res0: EitherT[List, Int, Int] = EitherT(List(Right(23), Left(3)))
def bitraverse[G[_], C, D](f: A => G[C], g: B => G[D])(implicit traverseF: Traverse[F], applicativeG: Applicative[G]): G[EitherT[F, C, D]]
def collectRight(implicit FA: Alternative[F], FM: Monad[F]): F[B]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] =
    |   EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> eitherT.collectRight
res0: List[Int] = List(123)
def combine(that: EitherT[F, A, B])(implicit F: Apply[F], B: Semigroup[B]): EitherT[F, A, B]

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)
def compare(that: EitherT[F, A, B])(implicit o: Order[F[Either[A, B]]]): Int
def ensure[AA >: A](onFailure: => AA)(f: B => Boolean)(implicit F: Functor[F]): EitherT[F, AA, B]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val e1: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> e1.ensure("error")(_ > 150)
res0: EitherT[List, String, Int] = EitherT(List(Left(error), Left(abc)))

scala> val e2: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> e2.ensure("error")(_ > 100)
res1: EitherT[List, String, Int] = EitherT(List(Right(123), Left(abc)))
def ensureOr[AA >: A](onFailure: B => AA)(f: B => Boolean)(implicit F: Functor[F]): EitherT[F, AA, B]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val e1: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> e1.ensureOr(_ => "error")(_ > 100)
res0: EitherT[List, String, Int] = EitherT(List(Right(123), Left(abc)))

scala> val e2: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> e2.ensureOr(_ => "error")(_ > 150)
res1: EitherT[List, String, Int] = EitherT(List(Left(error), Left(abc)))
def exists(f: B => Boolean)(implicit F: Functor[F]): F[Boolean]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> eitherT.exists(_ > 100)
res0: List[Boolean] = List(true, false)
def flatMap[AA >: A, D](f: B => EitherT[F, AA, D])(implicit F: Monad[F]): EitherT[F, AA, D]
def flatMapF[AA >: A, D](f: B => F[Either[AA, D]])(implicit F: Monad[F]): EitherT[F, AA, D]
def fold[C](fa: A => C, fb: B => C)(implicit F: Functor[F]): F[C]

Transform this EitherT[F, A, B] into a F[C].

Transform this EitherT[F, A, B] into a F[C].

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Left("456"), Right(123)))
scala> eitherT.fold(string => string.toInt, int => int)
res0: List[Int] = List(456, 123)
def foldF[C](fa: A => F[C], fb: B => F[C])(implicit F: FlatMap[F]): F[C]

Transform this EitherT[F, A, B] into a F[C].

Transform this EitherT[F, A, B] into a F[C].

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123),Left("abc")))
scala> eitherT.foldF(string => string.split("").toList, _ => List("123"))
res0: List[String] = List(123, a, b, c)
def foldLeft[C](c: C)(f: (C, B) => C)(implicit F: Foldable[F]): C
def foldRight[C](lc: Eval[C])(f: (B, Eval[C]) => Eval[C])(implicit F: Foldable[F]): Eval[C]
def forall(f: B => Boolean)(implicit F: Functor[F]): F[Boolean]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> eitherT.forall(_ > 100)
res0: List[Boolean] = List(true, true)
def getOrElse[BB >: B](default: => BB)(implicit F: Functor[F]): F[BB]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List,String,Int] = EitherT[List, String,Int](List(Right(123),Left("abc")))
scala> eitherT.getOrElse(456)
res0: List[Int] = List(123, 456)
def getOrElseF[BB >: B](default: => F[BB])(implicit F: Monad[F]): F[BB]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List,String,Int] = EitherT[List, String,Int](List(Right(123),Left("abc")))
scala> eitherT.getOrElseF(List(456))
res0: List[Int] = List(123, 456)
def getOrRaise[E](e: => E)(implicit F: MonadError[F, _ >: E]): F[B]

Like getOrElseF but accept an error E and raise it when the inner Either is Left

Like getOrElseF but accept an error E and raise it when the inner Either is Left

Equivalent to getOrElseF(F.raiseError(e)))

Example:

scala> import cats.data.EitherT
scala> import cats.implicits._
scala> import scala.util.{Success, Failure, Try}

scala> val eitherT: EitherT[Try,String,Int] = EitherT[Try,String,Int](Success(Left("abc")))
scala> eitherT.getOrRaise(new RuntimeException("ERROR!"))
res0: Try[Int] = Failure(java.lang.RuntimeException: ERROR!)
def isLeft(implicit F: Functor[F]): F[Boolean]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List,String,Int] = EitherT[List, String,Int](List(Right(123),Left("abc")))
scala> eitherT.isLeft
res0: List[Boolean] = List(false, true)
def isRight(implicit F: Functor[F]): F[Boolean]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List,String,Int] = EitherT[List, String,Int](List(Right(123),Left("abc")))
scala> eitherT.isRight
res0: List[Boolean] = List(true, false)
def leftFlatMap[BB >: B, C](f: A => EitherT[F, C, BB])(implicit F: Monad[F]): EitherT[F, C, BB]
def leftMap[C](f: A => C)(implicit F: Functor[F]): EitherT[F, C, B]
def leftSemiflatMap[D](f: A => F[D])(implicit F: Monad[F]): EitherT[F, D, B]
def leftSemiflatTap[C](f: A => F[C])(implicit F: Monad[F]): EitherT[F, A, B]
def map[D](f: B => D)(implicit F: Functor[F]): EitherT[F, A, D]
def mapAccumulate[S, C](init: S)(f: (S, B) => (S, C))(implicit traverseF: Traverse[F]): (S, EitherT[F, A, C])
def mapK[G[_]](f: FunctionK[F, G]): EitherT[G, A, B]

Modify the context F using transformation f.

Modify the context F using transformation f.

def merge[AA >: A](implicit ev: B <:< AA, F: Functor[F]): F[AA]
def orElse[C, BB >: B](default: => EitherT[F, C, BB])(implicit F: Monad[F]): EitherT[F, C, BB]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val e1: EitherT[Option,String,Int] = EitherT[Option, String,Int](Some(Right(123)))
scala> e1.orElse(EitherT[Option,Boolean,Int](Some(Right(456))))
res0: EitherT[Option, Boolean, Int] = EitherT(Some(Right(123)))

scala> val e2: EitherT[Option,String,Int] = EitherT[Option, String,Int](Some(Left("abc")))
scala> e2.orElse(EitherT[Option,Boolean,Int](Some(Left(true))))
res1: EitherT[Option, Boolean, Int] = EitherT(Some(Left(true)))
def partialCompare(that: EitherT[F, A, B])(implicit p: PartialOrder[F[Either[A, B]]]): Double
def recover(pf: PartialFunction[A, B])(implicit F: Functor[F]): EitherT[F, A, B]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List,String,Int] =
    |   EitherT[List, String,Int](List(Right(123),Left("abc")))
scala> val pf: PartialFunction[String, Int] = {case "abc" => 456}
scala> eitherT.recover(pf)
res0: EitherT[List, String, Int] = EitherT(List(Right(123), Right(456)))
def recoverWith(pf: PartialFunction[A, EitherT[F, A, B]])(implicit F: Monad[F]): EitherT[F, A, B]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List,String,Int] =
    |   EitherT[List, String,Int](List(Right(123),Left("abc")))
scala> val pf: PartialFunction[String, EitherT[List, String, Int]] =
    |   {case "abc" => EitherT[List, String, Int](List(Right(456)))}
scala> eitherT.recoverWith(pf)
res0: EitherT[List, String, Int] = EitherT(List(Right(123), Right(456)))
def rethrowT(implicit F: MonadError[F, _ >: A]): F[B]

Inverse of MonadError#attemptT Given MonadError[F, E :> A] transforms Either[F, A, B] to F[B] If the value was B, F[B] is successful If the value was A, F[B] is failed with E

Inverse of MonadError#attemptT Given MonadError[F, E :> A] transforms Either[F, A, B] to F[B] If the value was B, F[B] is successful If the value was A, F[B] is failed with E

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val e1: EitherT[Option, Unit, Int] = EitherT[Option, Unit, Int](Some(Right(123)))
scala> e1.rethrowT
res0: Option[Int] = Some(123)

scala> val e2: EitherT[Option, Unit, Int] = EitherT[Option, Unit, Int](Some(Left(())))
scala> e2.rethrowT
res1: Option[Int] = None

scala> import scala.util.Try
scala> import java.lang.Exception

scala> val e3: EitherT[Try, Throwable, String] = EitherT[Try, Throwable, String](Try(Right("happy cats")))
scala> e3.rethrowT
res2: util.Try[String] = Success(happy cats)

scala> val e4: EitherT[Try, Throwable, String] = EitherT[Try, Throwable, String](Try(Left(new Exception("sad cats"))))
scala> e4.rethrowT
res3: util.Try[String] = Failure(java.lang.Exception: sad cats)
def semiflatMap[D](f: B => F[D])(implicit F: Monad[F]): EitherT[F, A, D]
def semiflatTap[C](f: B => F[C])(implicit F: Monad[F]): EitherT[F, A, B]
def show(implicit show: Show[F[Either[A, B]]]): String
def subflatMap[AA >: A, D](f: B => Either[AA, D])(implicit F: Functor[F]): EitherT[F, AA, D]
def swap(implicit F: Functor[F]): EitherT[F, B, A]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List,String,Int] = EitherT[List, String,Int](List(Right(123),Left("abc")))
scala> eitherT.swap
res0: EitherT[List,Int,String] = EitherT(List(Left(123), Right(abc)))
def to[G[_]](implicit F: Functor[F], G: Alternative[G]): F[G[B]]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> eitherT.to[Option]
res0: List[Option[Int]] = List(Some(123), None)
def toIor(implicit F: Functor[F]): IorT[F, A, B]

Convert this EitherT[F, A, B] into an IorT[F, A, B].

Convert this EitherT[F, A, B] into an IorT[F, A, B].

def toNested: Nested[F, [_] =>> Either[A, _$22], B]

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.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> ff.ap(fa)
res0: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error)))
scala> EitherT((ff.toNested).ap(fa.toNested).value)
res1: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error), Left(error)))
def toNestedValidated(implicit F: Functor[F]): Nested[F, [_] =>> Validated[A, _$24], B]

Transform this EitherT[F, A, B] into a [[Nested]][F, Validated[A, *], B].

Transform this EitherT[F, A, B] into a [[Nested]][F, Validated[A, *], B].

Example:

scala> import cats.data.{EitherT, Validated}
scala> import cats.implicits._
scala> val f: Int => String = i => (i*2).toString
scala> val r1: EitherT[Option, String, Int => String] = EitherT.right(Some(f))
r1: cats.data.EitherT[Option,String,Int => String] = EitherT(Some(Right(<function1>)))
scala> val r2: EitherT[Option, String, Int] = EitherT.right(Some(10))
r2: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(10)))
scala> type ErrorOr[A] = Validated[String, A]
scala> (r1.toNestedValidated).ap(r2.toNestedValidated)
res0: cats.data.Nested[Option,ErrorOr,String] = Nested(Some(Valid(20)))
def toNestedValidatedNec(implicit F: Functor[F]): Nested[F, [_] =>> ValidatedNec[A, _$28], B]

Transform this EitherT[F, A, B] into a [[Nested]][F, ValidatedNec[A, *], B].

Transform this EitherT[F, A, B] into a [[Nested]][F, ValidatedNec[A, *], B].

def toNestedValidatedNel(implicit F: Functor[F]): Nested[F, [_] =>> ValidatedNel[A, _$26], B]

Transform this EitherT[F, A, B] into a [[Nested]][F, ValidatedNel[A, *], B].

Transform this EitherT[F, A, B] into a [[Nested]][F, ValidatedNel[A, *], B].

def toOption(implicit F: Functor[F]): OptionT[F, B]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> eitherT.toOption
res0: OptionT[List, Int] = OptionT(List(Some(123), None))
def toValidated(implicit F: Functor[F]): F[Validated[A, B]]
def toValidatedNec(implicit F: Functor[F]): F[ValidatedNec[A, B]]
def toValidatedNel(implicit F: Functor[F]): F[ValidatedNel[A, B]]
def transform[C, D](f: Either[A, B] => Either[C, D])(implicit F: Functor[F]): EitherT[F, C, D]
def traverse[G[_], D](f: B => G[D])(implicit traverseF: Traverse[F], applicativeG: Applicative[G]): G[EitherT[F, A, D]]
def valueOr[BB >: B](f: A => BB)(implicit F: Functor[F]): F[BB]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> eitherT.valueOr(_.length)
res0: List[Int] = List(123, 3)
def valueOrF[BB >: B](f: A => F[BB])(implicit F: Monad[F]): F[BB]

Example:

Example:

scala> import cats.implicits._
scala> import cats.data.EitherT

scala> val eitherT: EitherT[List, String, Int] = EitherT[List, String, Int](List(Right(123), Left("abc")))
scala> eitherT.valueOrF(string => List(string.length))
res0: List[Int] = List(123, 3)
def withValidated[C, D](f: Validated[A, B] => Validated[C, D])(implicit F: Functor[F]): EitherT[F, C, D]

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.invalidNel("error 1")
scala> val v2: Validated[NonEmptyList[Error], Int] = Validated.invalidNel("error 2")
scala> val eithert: EitherT[Option, Error, Int] = EitherT.leftT[Option, Int]("error 3")
scala> eithert.withValidated { v3 => (v1, v2, v3.toValidatedNel).mapN { case (i, j, k) => i + j + k } }
res0: EitherT[Option, NonEmptyList[Error], Int] = EitherT(Some(Left(NonEmptyList(error 1, error 2, error 3))))

Inherited methods

Inherited from:
Product