Ваш первый пункт примерно верен. Заявление
for (x <- list) yield f(x)
эквивалентно
list.map(x => f(x))
Но вы не совсем правы относительно того, как flatMap
используется, когда существует более одного списка.
Вызов flatMap
используется, если вы хотите перебрать другой список одновременно:
for (
x <- list1
y <- list2
) yield f(x, y)
Это эквивалентно
list1.flatMap(x => list2.map(y => f(x, y)))
Вызов map
заключен в вызов flatMap
, поэтому в результате получается простой список. Если внешний вызов был map
, то результатом был бы вложенный список.
Внутренний вызов всегда является вызовом map
, все внешние вызовы flatMap
. Так
for (
x <- list1
y <- list2
z <- list3
) yield f(x, y, z)
Есть
list1.flatMap(x => list2.flatMap(y => list3.map(z => f(x, y, z))))
В конце концов, лучшее, что можно сделать с for
, - это поэкспериментировать с ним, пока он не сделает то, что вы хотите, и через некоторое время он станет интуитивным.