Folding over lists
Recall the following from Chapter 1, Functional Patterns – the Building Blocks:
sumLazy [] = 0 sumLazy (x:xs) = x + sumLazy xs
This is captured by the recursive process foldr
:
sumLazy' = foldr (+) 0
On the other hand, we can write a strict sum function:
sumStrict acc [] = acc sumStrict acc (x:xs) = sumStrict (acc + x) xs
This is captured by the iterative process foldl
:
sumStrict' = foldl (+)
The foldl
function is tail recursive and strict in the accumulator. The foldr
function is non-tail recursive and lazy. In fact, the foldl
function is a special case of foldr
(https://wiki.haskell.org/Foldl_as_foldr).
Folding with monadic functions
Let's write a tail-recursive sum that does some IO at each accumulation step:
doSumStrict :: (Show a, Num a) => a -> [a] -> IO a doSumStrict acc [] = return acc doSumStrict acc (x:xs) = do putStrLn $ " + " ++ (show x) ++ " = " ++ (show acc') doSumStrict acc'...