Following Scala courses on Coursera, Martin Odersky showed an example code which is:
1 to 5 map ( i => i*i )
And he said the Range
gets transformed to a Vector
because they share the same interface (IndexedSeq
) and the result could not be represented as a Range
(it was more clear in its example since he generated a pair which is not representable as a Range
).
I'm not sure to understand because I think he said previously that in a for expression the 1st generator will determine the kind of element that will be yielded, and it seems not always true, at least for Range
.
And I'm not sure to understand why the output is Vector
, because Vector
may not be the only other one implementation that can represent the result computed above.
Can someone help me understand this part please?
map
secretly takes a CanBuildFrom
as an implicit argument. Its job is to produce a new collection given the one you've already got (and the type of the contents). Since Range
can't contain arbitrary stuff--not even arbitrary integers--there is no CanBuildFrom
that produces a Range
. The most specific supertype of Range
that does have a CanBuildFrom
is IndexedSeq
. The collection that is actually built by this is a Vector
.
As I'm sure Martin also explained, for
comprehensions correspond to (are translated into) chained invocations of the map
and flatMap
methods (and foreach
if you don't use yield
).
The reason why it generally results in a value of the type of the first generator is that map
and flatMap
generally return the same type as their receiver (map
on a List
returns a List
, etc.).
Now the problem with Range
s is that they cannot represent things that are not regular sequences of integers. As a consequence, the return type of map
and flatMap
as defined for Range
cannot be Range
. The next best match is Vector
, the prototypical implementation of an indexed sequence.
(If you look at the source code or even the Scala doc page I linked to, you will see that it is a little more complicated that just the return type, but conceptually, that is the reason. Edit: ...and now Rex Kerr just dropped the CanBuildFrom
bomb.)
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