typestar

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

  1. totalRainfall = foldr (+) 0 slots (+) between the elements, starting from the right end.
  2. runningProduct = foldl' (*) 1 walks left to right and forces each step, so unevaluated work never piles up.
  3. matchesPrelude checks those against sum xs and product xs, while summarize folds the same [Int] into a String.

Keywords and builtins used here

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.

Type this snippet

Step 2 of 3 in Higher-order, step 14 of 27 in Language basics.

← Previous Next →

Folds in other languages