mon
mon

Reputation: 22244

Scala For Comprehensions and For Loops

Objective

Trying to decrypt for comprehension and loop and their difference.

Expr1          ::=  `for' (`(' Enumerators `)' | `{' Enumerators `}')
                       {nl} [`yield'] Expr
Enumerators    ::=  Generator {semi Generator}
Generator      ::=  Pattern1 `<-' Expr {[semi] Guard | semi Pattern1 `=' Expr}
Guard          ::=  `if' PostfixExpr

Questions

For loop

A for loop for (enumsenums) ee executes expression ee for each binding generated by the enumerators enumsenums.

"Executes expression" means For Loop will not produce a value as the result but just apply some operation on each binding, hence it is basically a statement (in my understanding, in Scala, a expression returns a value, but a statement does not)?

For example, below there will produce none.

val mnemonic = Map('2' -> "ABC", '3' -> "DEF")
val a = for ((digit, str) <- mnemonic) str.contains(digit)

For comprehension

A for comprehension for (enumsenums) yield ee evaluates expression ee for each binding generated by the enumerators enumsenums and collects the results.

Whereas For Comprehension will produce a collection object as the result by collecting the result of evaluating the Expr expression for each binding. If so, what is the type of the collection crated? If it is a method, I can look into API document but which document specifies the type returned by For comprehension?

Upvotes: 4

Views: 1831

Answers (2)

Karl Bielefeldt
Karl Bielefeldt

Reputation: 49028

For comprehensions in Scala are syntactic sugar for map, flatMap, and filter. What type they return depends on what kind of collections you use in the comprehension, so:

val result1: List[Int] = for (x <- List(1,2,3)) yield x
val result2: String = for (x <- "string") yield x
val result3: Future[Unit] = for (x <- futureReturningFunction()) yield x

Upvotes: 1

dhg
dhg

Reputation: 52681

A for loop executes a statement for each item in a collection:

for (x <- List(1,2,3)) {
  println(x)
}

will print the numbers 1, 2, and 3. The return type of the loop is Unit, which is kind of like void would be in Java, so it doesn't make sense to assign it to anything.

A for comprehension, using the keyword yield, is just syntactic sugar for map or flatmap. These two statements are equivalent:

val y1 = for (x <- List(1,2,3)) yield x+1
val y2 = List(1,2,3).map(x => x+1)

Upvotes: 4

Related Questions