The accumulate function itertools.accumulate gives a running total.


For example, let’s try accumulating the numbers (1, 2, 3, 4, …):

>>> it = accumulate(count(1))

>>> list(islice(it, 8))
[1, 3, 6, 10, 15, 21, 28, 36]

Each subsequent element of the result is produced by adding the next value from the input to the previous value of the result. So the results are:

And so on.

A function that produces this sort of running total in Haskell is called a scan. There are a bunch of scan functions; the one that corresponds most closely to itertools.accumulate is called scanl1. scanl1 in Data.List and Prelude

λ> xs = scanl1 (+) [1..]

λ> take 8 xs

The first argument to scanl1 specifies what function we want to use for the aggregation. Here we’ve used (+) to get the same result as the Python function.

The func parameter

The Python function can also be used with an aggregation function; this is what the optional func parameter is for. Here we accumulate from the same sequence, this time using multiplication instead of addition:

>>> import operator

>>> it = accumulate(count(1), operator.mul)

>>> list(islice(it, 8))
[1, 2, 6, 24, 120, 720, 5040, 40320]

To do the same in Haskell, we use scanl1 again, this using (*) instead of (+) as the first argument.

λ> xs = scanl1 (*) [1..]

λ> take 8 xs

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