How is for comprehension returning None on comparison?

123 Views Asked by At

How is a below printed as None as the max is 3 here

val firstNum: Option[Int] = None
val secondNum: Option[Int] = Some(3)

val a = for {
  f <- firstNum
  s <- secondNum

} yield Math.max(f, s)

println(a)

output

None
2

There are 2 best solutions below

5
Ivan Kurchenko On BEST ANSWER

As in comment section was mentioned, your are using for-comprehension construction, which under the hood invokes flatMap method, which according to left identity monad law always works like this: None.flatmap(f) == None.

If you you want to find max between two Option[Int] and ignore if any of them absent, try to:


val firstNum: Option[Int] = None
val secondNum: Option[Int] = Some(3)
​
println(List(firstNum, secondNum).flatten.max)

Scatie: https://scastie.scala-lang.org/UbCy36hHS3iVLKEdqzqUCw

0
Tomer Shetah On

Just to add on top of the great answer by @IvanKurchenko. .max might throw an exception in case there are no elements in the List. For example:

List[Option[Int]](None).flatten.max

will throw an exception:

java.lang.UnsupportedOperationException: empty.max

Instead, you can use maxOption:

List(Some(3), None).flatten.maxOption

which will provide Some(3), and

List[Option[Int]](None).flatten.max

will provide None.