Подтвердить что ты не робот

Почему опция требует явного toList внутри для циклов?

Использование цикла for с простым параметром работает:

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

Но цикл по содержимому опции не выполняется:

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
                                               ^

... если параметр явно не преобразован в список:

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

Почему требуется явное преобразование списка? Является ли это идиоматическим решением?

4b9b3361

Ответ 1

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

переводится на

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

Метод flatMap на Option ожидает функцию, которая возвращает Option, но вы передаете функцию, которая возвращает List, и не имеет никакого неявного преобразования от List до Option.

Теперь, если вы сначала конвертируете Option в список, вместо него будет вызываться метод flatMap List, который ожидает функцию, возвращающую List, что и передается вам.

В этом конкретном случае я считаю, что наиболее идиоматическим решением является

Some(List(1,2,3)).flatten.toList