In explaining foldr
to Haskell newbies, the canonical definition is
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z
GHC cannot inline recursive functions, so
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
cannot be inlined. But
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
is not a recursive function. It is a non-recursive function with a local recursive definition!
This means that, as @bheklilr writes, in map (foldr (+) 0)
the foldr
can be inlined and hence f
and z
replaced by (+)
and 0
in the new go
, and great things can happen, such as unboxing of the intermediate value.