Skip to content

Instantly share code, notes, and snippets.

@danclien
Last active December 20, 2015 22:58
Show Gist options
  • Save danclien/6208408 to your computer and use it in GitHub Desktop.
Save danclien/6208408 to your computer and use it in GitHub Desktop.
Using `for` comprehensions vs only pattern matching for checking multiple Option[T] for None.
//Setup
def expensiveFunction(in: Int) : Option[Int] = {
println(s"Running expensive function for $in")
in match {
case 2 => None
case _ => Some(in)
}
}
// Test for comprehension
// Result: value3A is never evaluated
println("for comprehension")
lazy val value1A = expensiveFunction(1)
lazy val value2A = expensiveFunction(2)
lazy val value3A = expensiveFunction(3)
val result = for { x <- value1A; y <- value2A; z <- value3A } yield (x, y, z)
result match {
case None => println("Error")
case Some((x, y, z)) => println(s"$x, $y, $z")
}
// Test pattern matching
// Result: value1B, value2B, and value3B are all evaluated
println("Pattern matching only")
lazy val value1B = expensiveFunction(1)
lazy val value2B = expensiveFunction(2)
lazy val value3B = expensiveFunction(3)
(value1B, value2B, value3B) match {
case None => println("Error")
case ((Some(x), Some(y), Some(z)) => println(s"$x, $y, $z")
}
// Shorter for comprehesion if you don't need to do any error handling
for { x <- value1A; y <- value2A; z <- value3A } {
println(s"$x, $y, $z")
}
// With error handling. Doesn't feel like idiomatic Scala?
val success = for { x <- value1A; y <- value2A; z <- value3A } yield {
println(s"$x, $y, $z")
}
if (success == None) {
println("Error")
}
// With error handling. More idiomatic?
val result = for { x <- value1A; y <- value2A; z <- value3A } yield (x, y, z)
result match {
case Some((x, y, z)) => println(s"$x, $y, $z")
case None => println("Error")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment