Czytam "Programowanie w Scala 2nd Edition" i mam pewne pojęcie o monadzie z kursu Haskella, który zrobiłem. Jednak nie rozumiem, dlaczego następujący kod „magicznie” działa:W jaki sposób na wyrażenie z wieloma monadami tłumaczone jest słowo scala?
scala> val a: Option[Int] = Some(100)
a: Option[Int] = Some(100)
scala> val b = List(1, 2, 3)
b: List[Int] = List(1, 2, 3)
for (y <- b; x <- a) yield x;
res5: List[Int] = List(100, 100, 100)
Nie rozumiem powyższe ponieważ według książki rozdziale 23.4, wyrażenie for
jest tłumaczona na coś takiego:
b flatMap (y =>
a map (x => x)
)
Jestem zaskoczony, dlaczego powyższy kod się kompiluje, ponieważ y => a map (x => x)
jest typu Int => Option[Int]
, podczas gdy b.flatMap
oczekuje Int => List[Something]
.
Z drugiej strony, następujący kod NIE kompilować (co jest dobre, inaczej byłbym bardziej zagubiony):
scala> for (x <- a; y <- b) yield y;
<console>:10: error: type mismatch;
found : List[Int]
required: Option[?]
for (x <- a; y <- b) yield y;
^
Więc co jest magiczne z pierwszego przykładu?
'Opcja' nie jest' GenTraversableOnce' –
Istnieje niejawna konwersja nazwana opcja2Iterowalna zdefiniowana w obiekcie Option, która może zmienić opcję na Iterable. – Eastsun
@LuigiPlinge: Tak, jest. Zaktualizowałem odpowiedź, aby wyjaśnić, jak to działa. – ruakh