@@ -22,6 +22,7 @@ module Streamly.Internal.Data.Stream.IsStream.Common
2222 , relTimesWith
2323
2424 -- * Elimination
25+ , foldOn
2526 , fold
2627 , fold_
2728
@@ -104,6 +105,7 @@ import Prelude hiding (take, takeWhile, drop, reverse, concatMap, map, zipWith)
104105-- >>> import Streamly.Internal.Data.Stream.IsStream as Stream
105106-- >>> import qualified Streamly.Data.Array.Foreign as Array
106107-- >>> import qualified Streamly.Data.Fold as Fold
108+-- >>> import qualified Streamly.Internal.Data.Fold as Fold
107109-- >>> import qualified Streamly.Data.Unfold as Unfold
108110
109111------------------------------------------------------------------------------
@@ -266,6 +268,19 @@ relTimesWith = fmap snd . timesWith
266268-- Elimination - Running a Fold
267269------------------------------------------------------------------------------
268270
271+-- | We can create higher order folds using 'foldOn'. We can fold a number of
272+-- streams to a given fold efficiently with full stream fusion. For example, to
273+-- fold a list of streams on the same sum fold:
274+--
275+-- >>> concatFold = Prelude.foldl Stream.foldOn Fold.sum
276+--
277+-- >>> fold f = Fold.finish . Stream.foldOn f
278+--
279+-- /Internal/
280+{-# INLINE foldOn #-}
281+foldOn :: Monad m => Fold m a b -> SerialT m a -> Fold m a b
282+foldOn f s = D.foldOn f $ IsStream.toStreamD s
283+
269284-- | Fold a stream using the supplied left 'Fold' and reducing the resulting
270285-- expression strictly at each step. The behavior is similar to 'foldl''. A
271286-- 'Fold' can terminate early without consuming the full stream. See the