>>> 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
Control.Foldl.purely fold :: Monad m => Fold a b -> Producer a m () -> m b
>>> S.fold (+) 0 id $ each [1..10] 55 :> ()
>>> S.fold (*) 1 id $ S.fold (+) 0 id $ S.copy $ each [1..10] 3628800 :> (55 :> ())It can be used to replace a standard Haskell type with one more suited to writing a strict accumulation function. It is also crucial to the Applicative instance for Control.Foldl.Fold We can apply such a fold purely
Control.Foldl.purely S.fold :: Monad m => Fold a b -> Stream (Of a) m r -> m (Of b r)Thus, specializing a bit:
L.purely S.fold L.sum :: Stream (Of Int) Int r -> m (Of Int r) mapped (L.purely S.fold L.sum) :: Stream (Stream (Of Int)) IO r -> Stream (Of Int) IO rHere we use the Applicative instance for Control.Foldl.Fold to stream three-item segments of a stream together with their sums and products.
>>> S.print $ mapped (L.purely S.fold (liftA3 (,,) L.list L.product L.sum)) $ chunksOf 3 $ each [1..10] ([1,2,3],6,6) ([4,5,6],120,15) ([7,8,9],504,24) ([10],10,10)
>>> :{ let mySum :: [Int] -> Int mySum = fold $ \case Nil -> 0 Cons x sumXs -> x + sumXs :}
>>> mySum [10,11,12] 33In our running example, one layer consists of an Int and a list of recursive positions. In Tree Int, those recursive positions contain sub-trees of type Tree Int. Since we are working one layer at a time, the Base t a -> a function is not given a Tree Int, but a TreeF Int String. That is, each recursive position contains the String resulting from recursively folding the corresponding sub-tree.
>>> :{ let pprint1 :: Tree Int -> String pprint1 = fold $ \case NodeF i [] -> show i NodeF i ss -> show i ++ ": [" ++ intercalate ", " ss ++ "]" :}
>>> putStrLn $ pprint1 myTree 0: [1, 2, 3: [31: [311: [3111, 3112]]]]More generally, the t argument is the recursive value, the a is the final result, and the Base t a -> a function explains how to reduce a single layer full of recursive results down to a result.