How to initialize an Either to Right and specify the type of Left?

Starting Scala 2.13, Left comes with a Left#withRight method which allows upcasting Left[A, Nothing] to Either[A, B]:

Left("smthg").withRight[Int]
// Either[String, Int] = Left("smthg")
Left("smthg")
// Left[String, Nothing] = Left("smthg")

Same goes for the Right side and withLeft:

Right(42).withLeft[String]
// Either[String, Int] = Right(42)

which gives in your case:

List(5, 42, 7).foldLeft(Left("empty").withRight[Int]) {
  case (Left(_),  i) => Right(i)
  case (Right(s), i) => Right(s + i)
}
// Either[String, Int] = Right(54)

To supplement Xavier's answer, cats also provide utility methods for creating Either, for example, we can do:

import cats.implicits._

val right = 7.asRight[String] // Either[String, Int]

val left: = "hello cats".asLeft[Int] // Either[String, Int]

It might be useful if in case our project is using scala 2.12 or below.

In case we don't need whole cats library, we can, of course, borrow just extension functions for either:

implicit class EitherIdOps[A](private val obj: A) extends AnyVal {

  /** Wrap a value in `Left`. */
  def asLeft[B]: Either[A, B] = Left(obj)

  /** Wrap a value in `Right`. */
  def asRight[B]: Either[B, A] = Right(obj)

}

Tags:

Scala

Either