When do you choose to type a given function\'s return type as Seq
vs Iterable
vs Traversable
(or alternatively even deeper within Se
Seq
by default everywhere.IndexedSeq
when you need to access by index.These are the "common-sense" guidelines. They are simple, practical, and work well in practice while balancing principles and performance. The principles are:
Seq
satisfies both principles. As described in http://docs.scala-lang.org/overviews/collections/seqs.html:
A sequence is a kind of iterable that has a [finite] length and whose elements have fixed index positions, starting from 0.
90% of the time, your data is a Seq.
Other notes:
List
is an implementation type, so you shouldn't use it in an API. A Vector
for instance can't be used as a List
without going through a conversion.Iterable
doesn't define length
. Iterable
abstracts across finite sequences and potentially infinite streams. Most of the time one is dealing with finite sequences so you "have a length," and Seq
reflects that. Frequently you won't actually make use of length. But it's needed often enough, and is easy to provide, so use Seq
.Drawbacks:
There are some slight downsides to these "common-sense" conventions.
case head :: tail => ...
. You can use :+
and +:
as described here. Importantly, however, matching on Nil
still works as described in Scala: Pattern matching Seq[Nothing].Footnotes:
Map
here because the question, sensibly, doesn't ask about it.