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."
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.
=> 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).
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.
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.
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