Scala concepts: Lazy List

The 'LazyList' type (previously known as 'Stream' in Scala) is used to describe a potentially infinite list that evaluates only when necessary ('lazily').

Key example

This example shows how a LazyList is evaluated.

var itemsEvaluated = 0

def nextNumber(i: Int): Int = {
  itemsEvaluated += 1
  i + 1
}

val numbersFrom1: LazyList[Int] =
  LazyList.iterate(nextNumber(0))(i => nextNumber(i))

assert(itemsEvaluated == 0)

assert(numbersFrom1.head == 1)

assert(itemsEvaluated == 1)

assert(numbersFrom1.take(5).length == 5)

assert(itemsEvaluated == 5)

In particular, notice that the values that were pulled out are persisted for futher retrieval.

Self-recursion

Perhaps most interesting is the canonical example of how to use LazyList, where it refers to itself: the Fibonacci sequence. Have a look at the solution here: FibonacciLazyList.

Memory safety

LazyList may persist the items in memory for longer than needed, so do be careful about them, and test their edge cases when you work with them.

In practice, use cases of LazyList are few, and it may make more sense to use things like View, which provides lazy non-persistent evaluation. Ultimately, it will depend on your use case.