Reputation: 41909
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
Upvotes: 34
Views: 43164
Reputation: 962
If for some case you cannot use cats.Validated
then for cases when you have a collection (e.g. a List[_]
) of Either[L, R]
you could do this:
val list: List[Either[Throwable, String]] = ...
val throwablesList = list.collect { Left(ex) => ex }
Upvotes: 0
Reputation: 48410
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
Upvotes: 3
Reputation: 11297
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)
.
Upvotes: 2
Reputation: 3696
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
Upvotes: 23
Reputation: 6168
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)
Upvotes: 20