foldl f z [x1, x2, ..., xn] == (...((z `f` x1) `f` x2) `f`...) `f` xnNote that to produce the outermost application of the operator the entire input list must be traversed. Like all left-associative folds, foldl will diverge if given an infinite list. If you want an efficient strict left-fold, you probably want to use foldl' instead of foldl. The reason for this is that the latter does not force the inner results (e.g. z `f` x1 in the above example) before applying them to the operator (e.g. to (`f` x2)). This results in a thunk chain O(n) elements long, which then must be evaluated from the outside-in. For a general Foldable structure this should be semantically identical to:
foldl f z = foldl f z . toList
>>> foldl (+) 42 [1,2,3,4] 52Though the result below is lazy, the input is reversed before prepending it to the initial accumulator, so corecursion begins only after traversing the entire input string.
>>> foldl (\acc c -> c : acc) "abcd" "efgh" "hgfeabcd"A left fold of a structure that is infinite on the right cannot terminate, even when for any finite input the fold just returns the initial accumulator:
>>> foldl (\a _ -> a) 0 $ repeat 1 * Hangs forever *WARNING: When it comes to lists, you always want to use either foldl' or foldr instead.
foldl f z [x1, x2, ..., xn] == (...((z `f` x1) `f` x2) `f`...) `f` xnThe list must be finite.
>>> foldl (+) 0 [1..4] 10 >>> foldl (+) 42 [] 42 >>> foldl (-) 100 [1..4] 90 >>> foldl (\reversedString nextChar -> nextChar : reversedString) "foo" ['a', 'b', 'c', 'd'] "dcbafoo" >>> foldl (+) 0 [1..] * Hangs forever *
foldl' f z = foldl' f z . toList
foldl1 f = foldl1 f . toList
>>> foldl1 (+) [1..4] 10
>>> foldl1 (+) [] *** Exception: Prelude.foldl1: empty list
>>> foldl1 (+) Nothing *** Exception: foldl1: empty structure
>>> foldl1 (-) [1..4] -8
>>> foldl1 (&&) [True, False, True, True] False
>>> foldl1 (||) [False, False, True, True] True
>>> foldl1 (+) [1..] * Hangs forever *
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]
foldlMap1 f g (x1 :| [x2, ..., xn]) == (...(((f x1) `g` x2) `g`...) `g` xnNote that to produce the outermost application of the operator the entire input list must be traversed. This means that foldlMap1 will diverge if given an infinite list. If you want an efficient strict left-fold, you probably want to use foldlMap1' instead of foldlMap1. The reason for this is that the latter does not force the inner results (e.g. (f x1) `g` x2 in the above example) before applying them to the operator (e.g. to (`g` x3)). This results in a thunk chain <math> elements long, which then must be evaluated from the outside-in. For a general Foldable1 structure this should be semantically identical to:
foldlMap1 f g = foldlMap1 f g . toNonEmpty
foldlMap1' f z = foldlMap1' f z . toNonEmpty
>>> foldl1 (+) [1..4] 10 >>> foldl1 (+) [] *** Exception: Prelude.foldl1: empty list >>> foldl1 (-) [1..4] -8 >>> foldl1 (&&) [True, False, True, True] False >>> foldl1 (||) [False, False, True, True] True >>> foldl1 (+) [1..] * Hangs forever *
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
>>> bifoldl1 (+) (5, 7) 12
>>> bifoldl1 (+) (Right 7) 7
>>> bifoldl1 (+) (Left 5) 5
> bifoldl1 (+) (BiList [1, 2] [3, 4]) 10 -- ((1 + 2) + 3) + 4
>>> bifoldl1 (+) (BiList [1, 2] []) 3On empty structures, this function throws an exception:
>>> bifoldl1 (+) (BiList [] []) *** Exception: bifoldl1: empty structure ...
>>> bifoldlM (\a b -> print b >> pure a) (\a c -> print (show c) >> pure a) 42 ("Hello", True) "Hello" "True" 42
>>> bifoldlM (\a b -> print b >> pure a) (\a c -> print (show c) >> pure a) 42 (Right True) "True" 42
>>> bifoldlM (\a b -> print b >> pure a) (\a c -> print (show c) >> pure a) 42 (Left "Hello") "Hello" 42