Scala for () vs for {}

I am trying to understand for understanding in Scala, and I have many examples that I understand ...

One thing that is hard for me to figure out is :() vs for {}. I have tried both, and it seems that I can do one 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 will 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 the Coursera class that I accept. The professor did not mention the why in the video, and I was wondering if anyone else knew.

Thanks!

+5
source share
2 answers

From the specification syntax, it might seem that parsers and curly 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 semi-finished products, the following rules apply:

http://www.scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#newline-characters

I read and understood this section in the past, from which I vaguely recall the fact that new lines are included in curly brackets, i.e. char is used as nl , which serves as semi .

Therefore, you can put generators on separate lines instead of using semicolons.

This is the usual "semicolon output", which allows you not to write semicolons as operator terminators. Thus, a new line in the middle of the generator is not perceived as semi, for example:

 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) 
+7
source

In Scala () it is usually used when you have only one statement. Something like this would work:

 def encode(number: String): Set[Int] = if (number.isEmpty) Set() else { for ( split <- 1 to number.length // Only one statement in the comprehension ) split }.toSet 

Add one more and it will not be able to compile. The same is true for a map, for example

Ok

 List(1,2,3).map(number => number.toString ) 

Not OK (curly braces should be used)

 List(1,2,3).map(number => println("Hello world") number.toString ) 

Why? I have no idea:)

+4
source

Source: https://habr.com/ru/post/1205997/


All Articles