· haskell

Haskell: Viewing the steps of a reduce

I’ve been playing around with Haskell a bit over the last week and in the bit of code I was working on I wanted to fold over a collection but see the state of the fold after each step.

I remembered Don Syme showing me how to do something similar during the F# Exchange last year while we were writing some code to score a tennis game by using Seq.scan.

I didn’t realise there was also a scan function in Haskell which could be defined in terms of foldl if we wanted to:


foldscanl :: (a -> b -> a) -> a -> [b] -> [a]
foldscanl fn acc ls = foldl (\ x y -> x ++ [fn (last x) y]) [acc] ls

*Main> foldscanl (+) 0 [1..10]
[0,1,3,6,10,15,21,28,36,45,55]

The actual function is defined like so:


scanl                   :: (a -> b -> a) -> a -> [b] -> [a]
scanl f q ls            =  q : (case ls of
                                []   -> []
                                x:xs -> scanl f (f q x) xs)

*Main> scanl (*) 1 [1..10]
[1,1,2,6,24,120,720,5040,40320,362880,3628800]

I’ve been finding scanl particularly useful for working out whether the function I’m using to fold over the collection is actually working correctly.

There’s also a scanr if we want to fold over the collection from the right hand side.

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket