Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 822
mon Avatar asked Sep 06 '25 23:09

mon


2 Answers

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)
like image 180
dhg Avatar answered Sep 10 '25 04:09

dhg


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
like image 45
Karl Bielefeldt Avatar answered Sep 10 '25 05:09

Karl Bielefeldt