I'm trying to understand for comprehensions in Scala, and I have a lot of examples that I sort of understand...
One thing I'm having a hard time figuring out is for ( ) vs for { }. I've tried both, and it seems like I can do one thing in one but it breaks in the other.
For example, this does NOT work:
def encode(number: String): Set[List[String]] =
if (number.isEmpty) Set(List())
else {
for (
split <- 1 to number.length
word <- wordsForNum(number take split)
rest <- encode(number drop split)
) yield word :: rest
}.toSet
However, if you change it to { }, it does compile:
def encode(number: String): Set[List[String]] =
if (number.isEmpty) Set(List())
else {
for {
split <- 1 to number.length
word <- wordsForNum(number take split)
rest <- encode(number drop split)
} yield word :: rest
}.toSet
These examples are from a Coursera class I'm taking. The professor didn't mention the "why" in the video & I was wondering if anyone else knows.
Thanks!
From the syntax in the spec, it might seem that parens and braces are interchangeable:
http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#for-comprehensions-and-for-loops
but because the generators are separated by semis, the following rules kick in:
http://www.scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#newline-characters
I have read and understood that section in the past, from which I vaguely recall the gist that newlines are enabled in the braces, which is to say, a newline char is taken as nl
which serves as a semi
.
So you can put the generators on separate lines instead of using semicolons.
This is the usual "semicolon inference" that lets you not write semicolons as statement terminators. So the newline in the middle of the generator is not taken as a semi, for instance:
scala> for (c <-
| List(1,2,3)
| ) yield c+1
res0: List[Int] = List(2, 3, 4)
scala> for { c <-
| List(1,2,3)
| i = c+1
| } yield i
res1: List[Int] = List(2, 3, 4)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With