Knows Not Much Knows Not Much - 1 year ago 54
Scala Question

Avoiding nested Ifs when working with multiple Options and Eithers

When I am coding with options I find the fold method very useful. Instead of writing if defined statements I can do

opt.fold(<not_defined>){ defined => }

this is good. but what to do if we are working with multiple options. or multiple eithers. Now I have to resort to writing code like

if (x.isDefined && y.isRight) {
val z = getSomething(x.get)
if (z.isDefined) {

Depending on the number of things involved, this code becomes very nested.

is there a functional trick to make this code a little un-nested and concise.... like the fold operation above?

Answer Source

have you tried for comprehension? Assuming you don't want to treat individual errors or empty optionals:

import scala.util._

val opt1 = Some("opt1")
val either2: Either[Error, String] = Right("either2")
val try3: Try[String] = Success("try3")

for {
  v1 <- opt1
  v2 <- either2.right.toOption
  v3 <- try3.toOption
} yield {
  println(s"$v1 $v2 $v3")

Note that Either is not right biased, so you need to call the .right method on the for comprehension (I think cats or scalaz have a right biased Either). Also, we are converting the Either and the Try to optionals, discarding errors