Ahoy! I am learning Scala and making my way through the book Functional Programming in Scala. I have been playing around and found myself in the situation where I want to be able to turn a List of Iterators into an Iterator of Lists, where I start with an inital List[T] and have a function that creates an Iterator of T => Iterator[T]. I can map that across the initial list and get a List[Iterator[T]], but I ultimately want to turn that into an Iterator[List[T]].
I am certain that I have not explained that well, so here is an example:
def collatz(n: Int): Int =
n % 2 match
case 0 => n / 2
case 1 => 3 * n + 1
def collatzes(n: Int): Iterator[Int] =
Iterator.iterate(n)(collatz)
@main def main: Unit =
val inits = List(1, 2)
val iters = inits.map(collatzes)
val iter = ???
// want to turn this list of iterators into an iterator of lists,
// that gives me a list of the _.next of each iterator on each
// call of iter.next
I'm sure I could easily do what I need with a loop of some kind, but would love to know if there is an idiomatic functional way to do this type transform in Scala 3.
Cheers!
Hoping not to be too simplistic, I would probably just do the following:
The
iteratormethod is defined on allIterables, includingLists, and as you can imagine it returns anIteratorof the original collection. Themapfunction applies a function to each nestedIterator, turning each one in a concrete list. Since theIteratoris lazy, the nestedIterators will become a concreteListonly when you actually useiter.A word of warning:
Iterators are great, but you need to handle them with care if you wish to use a purely functional approach, sinceIterators are designed to be stateful, resulting in behavior that doesn't lend itself to make function referentially transparent, e.g.:For a lazy, memoized, built-in alternative to
Iterators you might want to have a look atLazyLists orViews.