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
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)
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)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With