13

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?

4

1 回答 1

12
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
于 2012-12-20T06:29:18.750 回答