DIfferent result of for/yield

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

DIfferent result of for/yield

Tomek K.-2
Can somebody explain me, please why there is a different type returned by these lines?


scala
> val a = Array(1,2,3,4,5)
a
: Array[Int] = Array(1, 2, 3, 4, 5)

scala
> for(i <- a) yield 2
res0
: Array[Int] = Array(2, 2, 2, 2, 2)

scala
> for(i <- 0 until a.length) yield 2
res1
: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 2, 2, 2, 2)


Why is there an Array type returned by first "for" loop and IndexedSeq/Vector by the second?

I tried similar example:

scala> class Car
defined class Car

scala
> val cars = Array(new Car, new Car, new Car, new Car, new Car)
cars
: Array[Car] = Array(Car@5527b211, Car@54cf7c6a, Car@78010562, Car@50756c76, Car@38aafb53)

scala
> for(car <- cars) yield new Car
res2
: Array[Car] = Array(Car@142213d5, Car@934b52f, Car@2630dbc4, Car@5ea4300e, Car@5a1c3cb4)

scala
> for(i <- 0 until cars.length) yield new Car
res3
: scala.collection.immutable.IndexedSeq[Car] = Vector(Car@2bfb583b, Car@73ae0257, Car@6fc1020a, Car@5762658b, Car@2629d5dc)


I thought these are just two ways of using "for" loop to go through a collection (like in C++ or Java - use "i" counter if you need to have an access to an index or use the second syntax if you need to do something on each element of a collection) but I don't understand why each of these calls produce different types (Array and IndexedSeq/Vector).

Thank you in advance

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: DIfferent result of for/yield

Lanny Ripple
Scala desugars for/yield into flatMap and map calls (plus some others if you do pattern matching or assignment).  The Scala collections library, in general, returns the type you started with.  So if you for/yield with an Array you'll get back an Array.  The to/until method returns a Range.  The type a Range turns into when mapped over is an IndexedSeq.  (It's trivial to map a Range into something that isn't a Range which is why you don't get a Range back.)  Scala's Predef, which is included automatically in your programs, uses List by default for Seqs and Vector for IndexedSeqs.

scala> for (i <- (1 to 10).toArray) yield 2
res2: Array[Int] = Array(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)



  -ljr

On Monday, January 9, 2017 at 12:27:34 PM UTC-6, Tomek K. wrote:
Can somebody explain me, please why there is a different type returned by these lines?


scala
> val a = Array(1,2,3,4,5)
a
: Array[Int] = Array(1, 2, 3, 4, 5)

scala
> for(i <- a) yield 2
res0
: Array[Int] = Array(2, 2, 2, 2, 2)

scala
> for(i <- 0 until a.length) yield 2
res1
: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 2, 2, 2, 2)


Why is there an Array type returned by first "for" loop and IndexedSeq/Vector by the second?

I tried similar example:

scala> class Car
defined class Car

scala
> val cars = Array(new Car, new Car, new Car, new Car, new Car)
cars
: Array[Car] = Array(Car@5527b211, Car@54cf7c6a, Car@78010562, Car@50756c76, Car@38aafb53)

scala
> for(car <- cars) yield new Car
res2
: Array[Car] = Array(Car@142213d5, Car@934b52f, Car@2630dbc4, Car@5ea4300e, Car@5a1c3cb4)

scala
> for(i <- 0 until cars.length) yield new Car
res3
: scala.collection.immutable.IndexedSeq[Car] = Vector(Car@2bfb583b, Car@73ae0257, Car@6fc1020a, Car@5762658b, Car@2629d5dc)


I thought these are just two ways of using "for" loop to go through a collection (like in C++ or Java - use "i" counter if you need to have an access to an index or use the second syntax if you need to do something on each element of a collection) but I don't understand why each of these calls produce different types (Array and IndexedSeq/Vector).

Thank you in advance

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: DIfferent result of for/yield

Scala - User mailing list
In reply to this post by Tomek K.-2
The for-yield is in your case a shorthand for

val a = Array(1,2,3,4,5)
a.map(_ => 2)
(0 until a.length).map(_ => 2)
 
The second case is slightly more interesting in that 0 until a.length is a Range that obviously cannot be preserved by a map. If you look at the spec

class Range(val start: Int, val end: Int, val step: Int)
extends scala.collection.AbstractSeq[Int]
with IndexedSeq[Int]
with scala.collection.CustomParallelizable[Int, ParRange]
with Serializable
{…}

you see that the obvious super type candidate is an indexed sequence. 

Regards

Axel

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Loading...