- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Iterable for all natural numbers?
Sat, 2009-01-24, 12:38
I often encounter the need for a non-strict, non-caching (non-lazy?) infinite
Iterable that simply contains all the natural numbers, or, more generally,
its Iterator computes the next element with some user-provided stateful
algorithm (internal state + a function on it). I still kind of expect to
have at least something like open-ended Ranges in the standard library. For
example, Range.from(Int), just like we have Stream.from(Int), but without
caching the computed elements. One specific use is indexing another infinite
sequence using zip. Is there such a thing in the Scala library after all?
Currently I use this code:
class InfiniteIterable[S, E](
init: S, calcNext: Array[S]=>E) extends Iterable.Projection[E]
{
override val hasDefiniteSize, isEmpty = false
def elements = new Iterator[E] {
val state: Array[S] = new Array[S](1); state(0) = init
val hasNext = true
def next = calcNext(state)
}
def apply(i:Int) = {
val elems = elements
for (j <- 1 until i) elems.next
elems.next
}
}
I can implement a sequence of naturals like this:
def naturals(start:Int) = new InfiniteIterable[Int, Int](start,
prevNat => {val curr = prevNat(0); prevNat(0) += 1; curr})
It is also quite simple to implement a Fibonacci sequence, for example:
val fibs = new InfiniteIterable[Queue[BigInt], BigInt](state, lastTwoArr =>
{
val lastTwo = lastTwoArr(0)
lastTwo enqueue (if (lastTwo.length < 2) 1 else lastTwo reduceLeft (_+_))
lastTwo.last
})
There are many inelegancies here (using Array as a mutable container of
state, for example), but it helps. I would like to know how to do this more
elegantly, leveraging the existing library to a greater extent. I can't help
but feel that I'm reinventing the wheel here, and a bumpy one, too.