>>> fold [[1, 2, 3], [4, 5], [6], []] [1,2,3,4,5,6]
>>> fold $ Node (Leaf (Sum 1)) (Sum 3) (Leaf (Sum 5)) Sum {getSum = 9}Folds of unbounded structures do not terminate when the monoid's (<>) operator is strict:
>>> fold (repeat Nothing) * Hangs forever *Lazy corecursive folds of unbounded structures are fine:
>>> take 12 $ fold $ map (\i -> [i..i+2]) [0..] [0,1,2,1,2,3,2,3,4,3,4,5] >>> sum $ take 4000000 $ fold $ map (\i -> [i..i+2]) [0..] 2666668666666
>>> foldlSC (\acc x -> if x == 0 then Left 0 else Right $! acc * x) 1 [1..6] 720 >>> foldlSC (\acc x -> if x == 0 then Left 0 else Right $! acc * x) 1 (0:error "Short-circuiting should keep this from happening") 0
>>> fold1 (1 :| [2, 3, 4 :: SG.Sum Int]) Sum {getSum = 10} >>> fold1 (4 :| [5, 10 :: SG.Product Int]) Product {getProduct = 200}
>>> foldMap1 SG.Sum (1 :| [2, 3, 4]) Sum {getSum = 10} >>> foldMap1 show (123 :| [456, 789, 0]) "1234567890"
foldl1' f [x0, x1, x2 ...] = f (f x0 x1) x2 ...
>>> foldl1' (++) ([1,2] :| [[3,4], [5,6]]) [1,2,3,4,5,6]
>>> foldr1 (+) 0 (1 :| [2, 3]) 6 >>> foldr1 (+) 1 $ Identity 3 4
>>> foldMapA @[Int] (Just . replicate 3) [1..3] Just [1,1,1,2,2,2,3,3,3]
>>> foldMapM @[Int] (Just . replicate 3) [1..3] Just [1,1,1,2,2,2,3,3,3]
>>> foldMap Sum [1, 3, 5] Sum {getSum = 9}
>>> foldMap Product [1, 3, 5] Product {getProduct = 15}
>>> foldMap (replicate 3) [1, 2, 3] [1,1,1,2,2,2,3,3,3]When a Monoid's (<>) is lazy in its second argument, foldMap can return a result even from an unbounded structure. For example, lazy accumulation enables Data.ByteString.Builder to efficiently serialise large data structures and produce the output incrementally:
>>> import qualified Data.ByteString.Lazy as L >>> import qualified Data.ByteString.Builder as B >>> let bld :: Int -> B.Builder; bld i = B.intDec i <> B.word8 0x20 >>> let lbs = B.toLazyByteString $ foldMap bld [0..] >>> L.take 64 lbs "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24"
>>> :set -XGeneralizedNewtypeDeriving >>> import Data.Bits (Bits, FiniteBits, xor, zeroBits) >>> import Data.Foldable (foldMap') >>> import Numeric (showHex) >>> >>> newtype X a = X a deriving (Eq, Bounded, Enum, Bits, FiniteBits) >>> instance Bits a => Semigroup (X a) where X a <> X b = X (a `xor` b) >>> instance Bits a => Monoid (X a) where mempty = X zeroBits >>> >>> let bits :: [Int]; bits = [0xcafe, 0xfeed, 0xdeaf, 0xbeef, 0x5411] >>> (\ (X a) -> showString "0x" . showHex a $ "") $ foldMap' X bits "0x42"@since base-4.13.0.0
foldl' f z = foldl' f z . toList@since base-4.6.0.0
foldlM f z t = do aa <- f z a bb <- f aa b ... xx <- f ww x yy <- f xx y return yy -- Just @return z@ when the structure is emptyFor a Monad m, given two functions f1 :: a -> m b and f2 :: b -> m c, their Kleisli composition (f1 >=> f2) :: a -> m c is defined by:
(f1 >=> f2) a = f1 a >>= f2Another way of thinking about foldlM is that it amounts to an application to z of a Kleisli composition:
foldlM f z t = flip f a >=> flip f b >=> ... >=> flip f x >=> flip f y $ zThe monadic effects of foldlM are sequenced from left to right. If at some step the bind operator (>>=) short-circuits (as with, e.g., mzero in a MonadPlus), the evaluated effects will be from an initial segment of the element sequence. If you want to evaluate the monadic effects in right-to-left order, or perhaps be able to short-circuit after processing a tail of the sequence of elements, you'll need to use foldrM instead. If the monadic effects don't short-circuit, the outermost application of f is to the rightmost element y, so that, ignoring effects, the result looks like a left fold:
((((z `f` a) `f` b) ... `f` w) `f` x) `f` y
>>> let f a e = do { print e ; return $ e : a } >>> foldlM f [] [0..3] 0 1 2 3 [3,2,1,0]
foldr f z [x1, x2, ..., xn] == x1 `f` (x2 `f` ... (xn `f` z)...)Note that since the head of the resulting expression is produced by an application of the operator to the first element of the list, given an operator lazy in its right argument, foldr can produce a terminating expression from an unbounded list. For a general Foldable structure this should be semantically identical to,
foldr f z = foldr f z . toList
>>> foldr (||) False [False, True, False] True
>>> foldr (||) False [] False
>>> foldr (\c acc -> acc ++ [c]) "foo" ['a', 'b', 'c', 'd'] "foodcba"
>>> foldr (||) False (True : repeat False) TrueBut the following doesn't terminate:
>>> foldr (||) False (repeat False ++ [True]) * Hangs forever *
>>> take 5 $ foldr (\i acc -> i : fmap (+3) acc) [] (repeat 1) [1,4,7,10,13]
{-# LANGUAGE DeriveFoldable #-} data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) deriving FoldableA more detailed description can be found in the Overview section of Data.Foldable#overview. For the class laws see the Laws section of Data.Foldable#laws.
>>> flipfoldl' (/) 5 [2,3] :: Rational 15 % 2This function can be useful for constructing containers from lists.
instance Bifoldable Either where bifoldMap f _ (Left a) = f a bifoldMap _ g (Right b) = g b instance Bifoldable (,) where bifoldr f g z (a, b) = f a (g b z)Some examples below also use the following BiList to showcase empty Bifoldable behaviors when relevant (Either and (,) containing always exactly resp. 1 and 2 elements):
data BiList a b = BiList [a] [b] instance Bifoldable BiList where bifoldr f g z (BiList as bs) = foldr f (foldr g z bs) asA minimal Bifoldable definition consists of either bifoldMap or bifoldr. When defining more than this minimal set, one should ensure that the following identities hold:
bifold ≡ bifoldMap id id bifoldMap f g ≡ bifoldr (mappend . f) (mappend . g) mempty bifoldr f g z t ≡ appEndo (bifoldMap (Endo . f) (Endo . g) t) zIf the type is also an instance of Foldable, then it must satisfy (up to laziness):
bifoldl const ≡ foldl bifoldr (flip const) ≡ foldr bifoldMap (const mempty) ≡ foldMapIf the type is also a Bifunctor instance, it should satisfy:
bifoldMap f g ≡ bifold . bimap f gwhich implies that
bifoldMap f g . bimap h i ≡ bifoldMap (f . h) (g . i)
bifold ≡ bifoldMap id id
>>> bifold (Right [1, 2, 3]) [1,2,3]
>>> bifold (Left [5, 6]) [5,6]
>>> bifold ([1, 2, 3], [4, 5]) [1,2,3,4,5]
>>> bifold (Product 6, Product 7) Product {getProduct = 42}
>>> bifold (Sum 6, Sum 7) Sum {getSum = 13}
bifoldMap f g ≡ bifoldr (mappend . f) (mappend . g) mempty
>>> bifoldMap (take 3) (fmap digitToInt) ([1..], "89") [1,2,3,8,9]
>>> bifoldMap (take 3) (fmap digitToInt) (Left [1..]) [1,2,3]
>>> bifoldMap (take 3) (fmap digitToInt) (Right "89") [8,9]
bifoldMapDefault f g ≡ getConst . bitraverse (Const . f) (Const . g)
bifoldl f g z ≡ foldl (acc -> either (f acc) (g acc)) z . toEitherListNote that if you want an efficient left-fold, you probably want to use bifoldl' instead of bifoldl. The reason is that the latter does not force the "inner" results, resulting in a thunk chain which then must be evaluated from the outside-in.
> bifoldl (+) (*) 3 (5, 7) 56 -- (5 + 3) * 7 > bifoldl (+) (*) 3 (7, 5) 50 -- (7 + 3) * 5 > bifoldl (+) (*) 3 (Right 5) 15 -- 5 * 3 > bifoldl (+) (*) 3 (Left 5) 8 -- 5 + 3