Question

In documentation of Option class written that following two examples are equivalent:

val name: Option[String] = request getParameter "name"
val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
println(upper getOrElse "")

and

val upper = for {
  name <- request getParameter "name"
  trimmed <- Some(name.trim)
  upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
} yield upper
println(upper getOrElse "")

But I don't understand how they can be equivalent: in first code block request getParameter "name" return instance of type Option[String], but in second code block statement name <- request getParameter "name" return instance of type String (I assumed that because next statement calls trim method on name variable (trim is not defined for Option[String])).

Was it helpful?

Solution

The conversion from for ... yield comprehension to map/flatMap method calls is done by the compiler. It's not required that the Option is an Iterable; the only thing necessary in this case is Option having map / flatMap methods:

  • flatMap if there are more -> calls after it in the same for block
  • map if it's the last one

We can create our own MyOption class like this:

case class MyOption[+T](value: T) {
  def flatMap[A](f: T => MyOption[A]): MyOption[A] = f(value)
  def map[A](f: T => A): MyOption[A] = MyOption(f(value))
  override def toString = s"Some($value)"
}

Then:

val result = for {
  a <- MyOption("one")
  b <- MyOption("two")
} yield a + "," + b
println(result)
// prints: Some(one,two)

OTHER TIPS

Option is an Iterable (there's an implicit option2Iterable method in Option companion object), that's why it can be used in someVar <- someOption clause. In fact, that arrow means "take elements from collection on the right".

So you're right, name in the 2nd example is a String.

In the 1st one you can see there are map and other Iterable methods used on Option. It is basically the same as for expression below, but calls methods directly, while for is just a syntax sugar and gets translated into the chain of method calls by the compiler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top