Search code examples
scalapattern-matchingfor-comprehension

Why does for-comprehension reverse the input list?


I have written this scala code:

scala> val lists = List(1, 2, 3) :: List.empty :: List(5, 2) :: Nil
lists: List[List[Int]] = List(List(1, 2, 3), List(), List(5, 2))

scala> val x = for {
     | list @ head :: _ <- lists
     | } yield list.size
x: List[Int] = List(3, 2)

this works but the output is a big confusing. How did the list get reversed?

I was hoping that the output list @ head would mean List(1, 2) :: 3

but the output of List(3, 2) is a little unexplained.


Solution

  • The list isn't reversed, you're returning a list that contains the sizes of the other lists. Your for-comprehension is roughly equivalent to this:

    lists.collect { case list @ head :: _ => list.size }
    

    list @ head :: _ matches only non-empty lists, and the list identifier is the entire List being mapped--which is getting mapped to its size. So the list of sizes would be List(3, 0, 2, 0), which is List(3, 2) when the empty lists are discarded.