Seq is a super-sign, so it is more general, it has characteristics common to all sequences, both linear and indexed.
If you are interested in the sequence generated by the Seq.apply method in the companion Seq object, we can take a look at the implementation.
Keep in mind that if you use Seq.apply, you mean that you just need Seq, and that your code does not care whether it is linear or indexed
Answer tl; dr then: you use LinearSeq or IndexedSeq when you need to have certain performance characteristics, you use more general Seq when you don't need a difference
This is a companion Seq object:
object Seq extends SeqFactory[Seq] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] def newBuilder[A]: Builder[A, Seq[A]] = immutable.Seq.newBuilder[A] }
The newBuilder[A] method is what is used to create Seq, as you can check in the Seq.apply method (defined in the GenericCompanion ):
def apply[A](elems: A*): CC[A] = { if (elems.isEmpty) empty[A] else { val b = newBuilder[A] b ++= elems b.result() } }
Now the question is: what does the immutable.Seq.newBuilder[A] assembly do? Letโs go and see, this time on an immutable.Seq companion object:
object Seq extends SeqFactory[Seq] { // stuff def newBuilder[A]: Builder[A, Seq[A]] = new mutable.ListBuffer }
It creates a mutable ListBuffer ! Why is this? This is because a mutable.ListBuffer also a Builder[A, Seq[A]] , that is, a class that the collection library uses to create new collections.
The actual output collection comes from this line (as you can see above):
b.result()
So what is the return type of ListBuffer.result() ? Release in ListBuffer:
// Implementation of abstract method in Builder def result: List[A] = toList
here you go: this is a list.
Seq(1,2,3) returns List[Int] under the hood, but the whole point here is that if you use Seq (), you donโt need to know which collection you have, because you are assuming a more abstract interface enough for your needs