Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Option require explicit toList inside for loops?

Using a for loop with a simple Option works:

scala> for (lst <- Some(List(1,2,3))) yield lst
res68: Option[List[Int]] = Some(List(1, 2, 3))

But looping over the contents of the Option does not:

scala> for (lst <- Some(List(1,2,3)); x <- lst) yield x
<console>:8: error: type mismatch;
 found   : List[Int]
 required: Option[?]
              for (lst <- Some(List(1,2,3)); x <- lst) yield x
                                               ^

...unless the Option is explicitly converted to a List:

scala> for (lst <- Some(List(1,2,3)).toList; x <- lst) yield x
res66: List[Int] = List(1, 2, 3)

Why is the explicit list conversion needed? Is this the idiomatic solution?

like image 386
Lorrin Avatar asked Dec 20 '12 05:12

Lorrin


1 Answers

for (lst <- Some(List(1,2,3)); x <- lst) yield x

is translated to

Some(List(1,2,3)).flatMap(lst => lst.map(x => x))

The flatMap method on Option expects a function that returns an Option, but you're passing a function that returns a List and there is no implicit conversion from List to Option.

Now if you convert the Option to a list first, the flatMap method of List will be called instead, which expects a function returning a List, which is what you are passing to it.

In this particular case, I think the most idiomatic solution is

Some(List(1,2,3)).flatten.toList
like image 142
Kim Stebel Avatar answered Nov 15 '22 10:11

Kim Stebel