I have realized that my typical way of passing Scala collections around could use some improvement.
def doSomethingCool(theFoos: List[Foo]) = { /* insert cool stuff here */ }
// if I happen to have a List
doSomethingCool(theFoos)
// but elsewhere I may have a Vector, Set, Option, ...
doSomethingCool(theFoos.toList)
I tend to write my library functions to take a List
as the parameter type, but I'm certain that there's something more general I can put there to avoid all the occasional .toList
calls I have in the application code. This is especially annoying since my doSomethingCool
function typically only needs to call map
, flatMap
and filter
, which are defined on all the collection types.
What are my options for that 'something more general'?
Here are more general traits, each of which extends the previous one:
GenTraversableOnce
GenTraversable
GenIterable
GenSeq
The traits above do not specify whether the collection is sequential or parallel. If your code requires that things be executed sequentially (typically, if your code has side effects of any kind), they are too general for it.
The following traits mandate sequential execution:
TraversableOnce
Traversable
Iterable
Seq
LinearSeq
The first one, TraversableOnce
only allows you to call one method on the collection. After that, the collection has been "used". In exchange, it is general enough to accept iterators as well as collections.
Traversable
is a pretty general collection that has most methods. There are some things it cannot do, however, in which case you need to go to Iterable
.
All Iterable
implement the iterator
method, which allows you to get an Iterator
for that collection. This gives it the capability for a few methods not present in Traversable
.
A Seq[A]
implements the function Int => A
, which means you can access any element by its index. This is not guaranteed to be efficient, but it is a guarantee that each element has an index, and that you can make assertions about what that index is going to be. Contrast this with Map
and Set
, where you cannot tell what the index of an element is.
A LinearSeq
is a Seq
that provides fast head
, tail
, isEmpty
and prepend. This is as close as you can get to a List
without actually using a List
explicitly.
Alternatively, you could have an IndexedSeq
, which has fast indexed access (something List
does not provide).
See also this question and this FAQ based on it.
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