What exactly happens when you evaluate expression: Seq(1,2,3)
?
I am new to Scala and I am now a bit confused about various collection types. Seq is a tr
Seq
is the val
of:
package object scala {
...
val Seq = scala.collection.Seq
...
}
it points to object scala.collection.Seq
:
/** $factoryInfo
* The current default implementation of a $Coll is a `List`.
* @define coll sequence
* @define Coll `Seq`
*/
object Seq extends SeqFactory[Seq] {
/** $genericCanBuildFromInfo */
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
def newBuilder[A]: Builder[A, Seq[A]] = immutable.Seq.newBuilder[A]
}
and when you do Seq(1,2,3)
the apply()
method is ivoked from scala.collection.generic.GenericCompanion
abstract class:
/** A template class for companion objects of "regular" collection classes
* represent an unconstrained higher-kinded type. Typically
* such classes inherit from trait `GenericTraversableTemplate`.
* @tparam CC The type constructor representing the collection class.
* @see [[scala.collection.generic.GenericTraversableTemplate]]
* @author Martin Odersky
* @since 2.8
* @define coll collection
* @define Coll `CC`
*/
abstract class GenericCompanion[+CC[X] <: GenTraversable[X]] {
...
/** Creates a $coll with the specified elements.
* @tparam A the type of the ${coll}'s elements
* @param elems the elements of the created $coll
* @return a new $coll with elements `elems`
*/
def apply[A](elems: A*): CC[A] = {
if (elems.isEmpty) empty[A]
else {
val b = newBuilder[A]
b ++= elems
b.result()
}
}
}
and finally, this method builds an object of Seq
type by code mentioned above
And most importantly what is the type of the returned value?
object MainClass {
def main(args: Array[String]): Unit = {
val isList = Seq(1,2,3).isInstanceOf[List[Int]]
println(isList)
}
}
prints:
true
So, the type is scala.collection.immutable.List
Also in REPL I see that the contents of the evaluated expression is actually a List(1,2,3), but the type is apparently Seq[Int].
The default implementation of Seq
is List
by the code mentioned above.
Why is not an Indexed collection type, like Vector? What is the logic behind all that?
Because of immutable design. The list is immutable and to make it immutable and have a constant prepend operation but O(n) append operation cost and O(n) cost of accessing n'th element. The Vector
has a constant efficient implementation of access and add elements by id, prepend and append operations.
To have a better understanding of how the List is designed in Scala, see https://mauricio.github.io/2013/11/25/learning-scala-by-building-scala-lists.html