Reputation: 1037
I am trying out Scala exercise where for expression is converted to higher order function - flatMap, filter and map. I don't understand how the input to map(List(author1,author2)) is translated to book.title.
Input:
val books:List[Book] = List(
Book(title = "kids watching", authors = List("Aavik","Arjun"))
)
For expression:
for{
book <- books
name <- book.authors
if name.startsWith("Aavik")
} yield book.title
Higher order function:
books flatMap(book =>
book.authors filter(name => name startsWith("Aavik")) map(_ => book.title))
Input to map is List("Aavik") and how does the map relates to book.title?
Upvotes: 2
Views: 115
Reputation: 93
if I got your question right, in the above example i.e
for{
book <- books
name <- book.authors
if name.startsWith("Aavik")
} yield book.title
This will actually be converted to:
books.flatMap(((book) => book.authors.withFilter(((name) => name.startsWith("Aavik"))).map(((name) => book.title))))
So, as you can see we have book that is the input to the flatMap and it can be accessed anywhere inside it. So there is no issue in accessing book.title inside map as map is enclosed inside the flatMap.
Let me know if you want more clarity.
Upvotes: 0
Reputation: 1348
@Aavik please read How does yield work? article.
Desugared version of your example will look like:
case class Book(title: String, authors: List[String])
val books: List[Book] = List(
Book(title = "kids watching", authors = List("Aavik","Arjun"))
)
books.flatMap { (book: Book) =>
book.authors.withFilter { (name: String) =>
name.startsWith("Aavik")
}.map { _ =>
book.title
}
}
As you see map { _ => book.title }
has the same scope as book
variable. You can run this example in Scastie.
Ammonite REPL desugar can help to investigate how does Scala translate for-comprehensions.
Upvotes: 1