2012-12-20 10 views
13

za pomocą pętli for z prostym opcja działa:Dlaczego opcja wymaga jawnie toList inside dla pętli?

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

Ale zapętlenie nad treścią opcja nie:

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 
              ^

... chyba, że ​​opcja ta jest wyraźnie konwertowane do listy:

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

Dlaczego wymagana jest konwersja jawnej listy? Czy to jest idiomatyczne rozwiązanie?

Odpowiedz

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

jest tłumaczona na

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

Sposób flatMap na Option spodziewa funkcję, która zwraca Option, ale jesteś przechodzącą funkcję zwracającą List i nie jest niejawna konwersja z List do Option.

Teraz, jeśli konwersja Option do listy pierwsze, metoda ListflatMap zostanie wywołana zamiast, który spodziewa funkcję przekazujących List, który jest to, czego przechodząc do niego.

W tym konkretnym przypadku, myślę, że najbardziej idiomatyczne rozwiązaniem jest

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

Dlatego dla '(LST <- Niektórzy (List (1,2,3)) get; x <- Option (LST)) wydajność x' działa również. Ciekawy. – sberry

Powiązane problemy