[Move foldr, foldl explanationny bits around. Bryan O'Sullivan **20070919224457] { hunk ./en/ch04-fp.xml 976 - out each step in the evaluation of niceSum - [1,2,3]. - - -step 0 (1:[2,3]) == step (0 + 1) [2,3] - - -step (0 + 1) (2:[3]) == step ((0 + 1) + 2) [3] - - -step ((0 + 1) + 2) [3] == step (((0 + 1) + 2) + 3) [] - - -step (((0 + 1) + 2) + 3) [] == (((0 + 1) + 2) + 3) - - + out each step in the evaluation of step function + when we call niceSum [1,2,3]. + + &Fold.hs:foldl.expand; hunk ./en/ch04-fp.xml 1085 - Let's follow the same manual expansion steps with + Let's follow the same manual evaluation process with hunk ./en/ch04-fp.xml 1090 - - - step (1:[2,3]) == 1 + step [2,3] - - -1 + step (2:[3]) == 1 + (2 + step [3]) - - -1 + (2 + step [3]) == 1 + (2 + (3 + step [])) - - -1 + (2 + (3 + step [])) == 1 + (2 + (3 + 0)) - - + &Fold.hs:foldr.expand; hunk ./en/ch04-fp.xml 1106 - 1 : 2 : 3 : [] -1 + 2 + 3 + 0 - + &Fold.hs:foldr.sub; hunk ./en/ch04-fp.xml 1157 - + + Understanding foldl in terms of foldr + hunk ./en/ch04-fp.xml 1166 - + + All you'll need to do is follow the same manual + evaluation steps as we did to see what + foldl and foldr + were really doing. + hunk ./en/ch04-fp.xml 1175 - foldr is more basic than + foldr is more basic than hunk ./en/ch04-fp.xml 1186 - Another useful way to think about the way - foldr works is that it - transforms its input list. Its first two - arguments are what to do with each head/tail element of - the list, and what to substitute at the end - of the list. + Returning to our earlier intuitive explanation + of what foldr does, another useful way to + think about it is that it transforms its + input list. Its first two arguments are what to do + with each head/tail element of the list, and + what to substitute for the end of the + list. hunk ./en/ch04-fp.xml 1222 - Now that we can think in terms of transforming a list, it - becomes easier for us to reason about operations like summing a - list. We replace the empty list with zero, which becomes our - first accumulator value. We then apply the - (+) function to each element of the list - and an accumulator value, to give a new accumulator - value. - - &fold.ghci:sum; - - Knowing that foldr transforms a list - from right to left, we can unroll the - application of it by hand to see the intermediate accumulators - that it produces. - - &fold.ghci:sum.steps; + Here, we're replacing each list constructor with another + list constructor, but we're replacing the empty list with the + list we want to append onto the end of our first list. hunk ./examples/ch04/Fold.hs 58 +{-- snippet foldl.expand --} +-- step 0 (1:2:3:[]) == step (0 + 1) (2:3:[]) +-- step (0 + 1) (2:3:[]) == step ((0 + 1) + 2) (3:[]) +-- step ((0 + 1) + 2) [3] == step (((0 + 1) + 2) + 3) [] +-- step (((0 + 1) + 2) + 3) [] == (((0 + 1) + 2) + 3) +{-- /snippet foldl.expand --} + +{-- snippet foldr.expand --} +-- step (1:2:3:[]) == 1 + step (2:3:[]) +-- 1 + step (2:3:[]) == 1 + (2 + step (3:[]) +-- 1 + (2 + step [3]) == 1 + (2 + (3 + step [])) +-- 1 + (2 + (3 + step [])) == 1 + (2 + (3 + 0)) +{-- /snippet foldr.expand --} + +{-- snippet foldr.sub --} +-- 1 : 2 : 3 : [] +-- 1 + 2 + 3 + 0 +{-- /snippet foldr.sub --} hunk ./examples/ch04/fold.ghci 1 -:m +Fold.hs +:load Fold.hs hunk ./examples/ch04/fold.ghci 12 ---# sum - -foldr (+) 0 [1,2,3] - ---# sum.steps - -foldr (+) 0 [] -foldr (+) 0 [3] -foldr (+) 0 [2,3] -foldr (+) 0 [1,2,3] - }