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 http://msdn.microsoft.com/en-us/library/ee340364.aspx.
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]
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.
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.