Вопрос

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

Это было полезно?

Решение

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.

Другие советы

in this for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar comprehension, the 1st generator is of Type scala.collection.immutable.Range.Inclusive the yield result vector is of Type scala.collection.immutable.IndexedSeq[Int] and if you check the class Range: http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Range

it shows Range extends/mixin the IndexedSeq. the super type IndexedSeq is compatible with the sub type Range.

If the result can not be represented by a range(as the previous answer explained), it will 'search for' the super type to represent the result.

enter image description here

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top