I think you are over-complicating things: getLines
does returns an iterator, as you said. You can materialise an iterator into a list using its .toList
method:
Source.fromFile("myfile.txt").getLines.toList
As an aside, what if the .toList
method didn't exist? You could then use a recursive function to convert an iterator to a list (if you really wanted to -- a simple reduce would be simpler and probably faster):
def materialize[T](it:Iterator[T]):List[T] =
materializeHelper(it, List.empty[T])
def materializeHelper[T](it:Iterator[T], accumulator:List[T]):List[T] =
if(!it.hasNext) {
accumulator.reverse
}
else {
materializeHelper(it, it.next :: accumulator)
}
In general, you should prefer using higher-order functions to recursion or iteration whenever possible. Higher-order functions minimise your exposure to moving parts, which is where bugs get introduced. Consider the same code implemented with foldLeft
:
def materialize[T](it:Iterator[T]):List[T] =
it.foldLeft(List.empty[T]) {
(accumulator, elem) => elem :: accumulator
}.reverse
This is less error-prone: you don't have to deal with advancing the iterator directly, or with boundary conditions when the iterator is empty.