Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return type of Scala for/yield

I'm reading through Scala for the Impatient and I've come across something that's got me scratching my head.

The following returns a String:

scala> for ( c<-"Hello"; i <- 0 to 1) yield (c+i).toChar
res68: String = HIeflmlmop

But this returns a Vector:

scala> for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar
res72: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p)

The text preceding these two examples reads...

"When the body of the for loop starts with yield, then the loop constructs a collection of values, one for each iteration...This type of loop is called a for comprehension. The generated collection is compatible with the first generator.

If the generated collection is compatible with the first generator, then why isn't the second example returning a type of Range, as in the following:

scala> val range = 0 to 1
range: scala.collection.immutable.Range.Inclusive = Range(0, 1)

Or am I misinterpreting entirely what the text means by, "...the generated collection is compatible with the first generator."

like image 400
chb Avatar asked May 11 '13 16:05

chb


People also ask

What is yield function in Scala?

Yield is a keyword in scala that is used at the end of the loop. We can perform any operation on the collection elements by using this for instance if we want to increment the value of collection by one. This will return us to the new collection.

What does => mean in Scala?

=> is the "function arrow". It is used both in function type signatures as well as anonymous function terms. () => Unit is a shorthand for Function0[Unit] , which is the type of functions which take no arguments and return nothing useful (like void in other languages).

What are for comprehensions in Scala?

Scala offers a lightweight notation for expressing sequence comprehensions. Comprehensions have the form for (enumerators) yield e , where enumerators refers to a semicolon-separated list of enumerators. An enumerator is either a generator which introduces new variables, or it is a filter.


1 Answers

for-comprehensions are desugared to a series of map, flatMap and filter operations.

When you use map on a Range, you get a Vector output:

scala> 0 to 2 map (x => x * x)
res12: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 4)

This is because a Range is a very simple sort of collection, that is essentially just two three numbers: a start value, an end value and a step. If you look at the result of the mapping above, you can see that the resulting values cannot be represented by something of the Range type.

like image 153
Luigi Plinge Avatar answered Sep 16 '22 15:09

Luigi Plinge