Чтобы ответить на первый вопрос, я думаю, вы правы насчет next <- moves map path.extend
Я предполагаю, что вы говорите о «понимании». Например,
val a = List (1, 3, 5)
a.map(b => b * b)
//> res0: List[Int] = List(1, 9, 25)
for {
blah <- a map (b => b * b)
} yield blah
//> res1: List[Int] = List(1, 9, 25)
Эти два результата возвращают одинаковый результат и эквивалентны в Scala.
Итак, мы говорим для каждого элемента «a» вызов функции (b => b * b).
В вашем примере это больше, как этот сценарий:
case class Song(artists:List[String], title: String)
val songs = List(Song(List("Michael Jackson", "Janet Jackson"), "Scream"),
Song(List("Janet"), "Unbreakable"))
for {
song <- songs
artist <- song.artists
if artist startsWith "Mic"
} yield song.title
//> res0: List[String] = List(Scream)
songs.flatMap(
song => song.artists.withFilter(artist => artist startsWith "Mic").map(artist => song.title)
)
//> res1: List[String] = List(Scream)
Вы можете увидеть это также эквивалентны, но «для-понимания» легче читать.
Синтаксис Scala позволяет выражать стандартный вызов метода 'obj.meth (arg)' с пробелами 'obj meth arg'. – jwvh