Folds in Haskell
foldr and foldl' both collapse a list to one value; they differ in direction and in when work happens.
module Folds where
-- foldr slots (+) between the elements, starting from the right end
totalRainfall :: [Int] -> Int
totalRainfall = foldr (+) 0
-- foldl' walks left to right and forces each step, so nothing piles up
-- as unevaluated work; base 4.20 exports it straight from the Prelude
runningProduct :: [Int] -> Int
runningProduct = foldl' (*) 1
-- sum and product are these same two folds under friendlier names
matchesPrelude :: [Int] -> Bool
matchesPrelude xs =
sum xs == totalRainfall xs && product xs == runningProduct xs
-- the result type is free to differ from the element type
summarize :: [Int] -> String
summarize = foldr (\mm acc -> show mm ++ " mm; " ++ acc) "end"
How it works
totalRainfall = foldr (+) 0slots(+)between the elements, starting from the right end.runningProduct = foldl' (*) 1walks left to right and forces each step, so unevaluated work never piles up.matchesPreludechecks those againstsum xsandproduct xs, whilesummarizefolds the same[Int]into aString.
Keywords and builtins used here
BoolIntStringmatchesPreludemodulerunningProductsummarizetotalRainfallwhere
The run, in numbers
- Lines
- 19
- Characters to type
- 685
- Tokens
- 84
- Three-star pace
- 70 tpm
At the three-star pace of 70 tokens a minute, this run takes about 72 seconds.
Step 2 of 3 in Higher-order, step 14 of 27 in Language basics.