Question

Besides using match, is there an Option-like way to getOrElse the actual content of the Right or Left value?

scala> val x: Either[String,Int] = Right(5)
scala> val a: String = x match { 
                                case Right(x) => x.toString
                                case Left(x) => "left" 
                       }
a: String = 5
Was it helpful?

Solution 2

I don't particularly like Either and as a result I'm not terribly familiar with it, but I believe you're looking for projections: either.left.getOrElse or either.right.getOrElse.

Note that projections can be used in for-comprehensions as well. This is an example straight from the documentation:

def interactWithDB(x: Query): Either[Exception, Result] =
  try {
    Right(getResultFromDatabase(x))
  } catch {
    case ex => Left(ex)
  }

// this will only be executed if interactWithDB returns a Right
val report =
  for (r <- interactWithDB(someQuery).right) yield generateReport(r)
if (report.isRight)
  send(report)
else
  log("report not generated, reason was " + report.left.get)

OTHER TIPS

Nicolas Rinaudo's answer regarding calling getOrElse on either the left or right projection is probably the closest to Option.getOrElse.

Alternatively, you can fold the either:

scala> val x: Either[String,Int] = Right(5)
x: Either[String,Int] = Right(5)

scala> val a: String = x.fold(l => "left", r => r.toString)
a: String = 5

As l is not used in the above fold, you could also write x.fold(_ => "left", r => r.toString)

Edit: Actually, you can literally have Option.getOrElse by calling toOption on the left or right projection of the either, eg,

scala> val o: Option[Int] = x.right.toOption
o: Option[Int] = Some(5)

scala> val a: String = o.map(_.toString).getOrElse("left")
a: String = 5

Given type A on both sides, that is, Either[A, A], we can use Either.merge

...to extract values from Either instances regardless of whether they are Left or Right.

Note if left and right types differ then result is least upper bound of the two types which may become in worst case Any:

val e: Either[Int, String] = Right("hello")
e.merge // hello: Any

In Scala 2.12 there is a getOrElse method for getting the "right" value but you cannot use it for the "left" value directly. However, you can do it like this: e.swap.getOrElse(42).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top