Iteration to infinity

This lesson is about functions that produce simple never-ending iterators. The ability to represent concepts like counting upward from one and repeating an item indefinitely is a big part of what distinguishes iterators from lists in Python. In Haskell we describe things like Python iterators as “lazy” because elements are not evaluated until they are needed. Python lists, in contrast, we describe as “strict”.


The count function itertools.count produces a sequence of numbers incrementing by some fixed interval. This iterator is always infinite, so we will use islice to take portions of it when we give examples.

The start parameter

The first parameter of count specifies where to start. For example, count(2) enumerates the integers increasing from 2.

>>> it = count(2)

>>> list(islice(it, 5))
[2, 3, 4, 5, 6]

The Haskell equivalent is enumFrom; enumFrom in Prelude for example, enumFrom 2 enumerates the integers increasing from 2.

λ> take 5 (enumFrom 2)

This is commonly written using range syntax; [2..] has the same meaning.

λ> take 5 [2..]

The step parameter

The optional second parameter to count specifies how much each subsequent value will change from the previous value. By default, it increments by 1. Here we show incrementing by two:

>>> it = count(10, 2)

>>> list(islice(it, 5))
[10, 12, 14, 16, 18]

The simplest way to accomplish this in Haskell is with a more general function called iterate. iterate in Data.List and Prelude

iterate :: (a -> a) -> a -> [a]

The first parameter to iterate specifies how each subsequent value will change from the previous value. For example, to increment by two:

λ> xs = iterate (\x -> x + 2) 10

λ> take 5 xs

You can use a negative step to count downward:

>>> it = count(10, -1)

>>> list(islice(it, 5))
[10, 9, 8, 7, 6]

Just as you can use (\x -> x - 1) (“subtract one”) as the function argument to iterate:

λ> xs = iterate (\x -> x - 1) 10

λ> take 5 xs


To cycle a list itertools.cycle is to replay it over and over in a never-ending loop.

>>> it = cycle('ha')

Here we print the first six elements of the infinite iterator:

>>> ''.join(islice(it, 6))

The Haskell function cycle in Data.List and Prelude is the same.

λ> xs = cycle "ha"

λ> take 6 xs


The repeat function itertools.repeat is similar to cycle, but its parameter is a single value, not an iterable.

Infinite repetition

It produces a never-ending repetition of its argument.

>>> it = repeat("ha")

Again we demonstrating by printing only the first handful of outputs:

>>> list(islice(it, 5))
['ha', 'ha', 'ha', 'ha', 'ha']

Again the Haskell function repeat in Data.List and Prelude is the same as the Python function.

λ> xs = repeat "ha"

λ> take 5 xs

The times parameter

The optional times parameter allows us to specify some fixed number of repetitions to get a finite result.

>>> it = repeat("ha", 5)

>>> list(it)
['ha', 'ha', 'ha', 'ha', 'ha']

Because Haskell does not overload function names with differing arities as Python does, the Haskell equivalent replicate in Data.List and Prelude is a separate function with a different name: replicate.

λ> replicate 5 "ha"

Join Type Classes for courses and projects to get you started and make you an expert in FP with Haskell.