@@ -218,6 +218,7 @@ module Streamly.Internal.Data.Fold.Type
218218 -- * Nested Application
219219 , concatMap
220220 , many
221+ , manyPost
221222 , intervalsOf
222223 , chunksOf
223224 , chunksOf2
@@ -1006,6 +1007,61 @@ many (Fold sstep sinitial sextract) (Fold cstep cinitial cextract) =
10061007 Partial s -> cextract s
10071008 Done b -> return b
10081009
1010+-- |Like many, but inner fold emits an output at the end even if no input is
1011+-- received.
1012+--
1013+-- /Internal/
1014+--
1015+-- /See also: Streamly.Prelude.concatMap, Streamly.Prelude.foldMany/
1016+--
1017+{-# INLINE manyPost #-}
1018+manyPost :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
1019+manyPost (Fold sstep sinitial sextract) (Fold cstep cinitial cextract) =
1020+ Fold step initial extract
1021+
1022+ where
1023+
1024+ -- cs = collect state
1025+ -- ss = split state
1026+ -- cres = collect state result
1027+ -- sres = split state result
1028+ -- cb = collect done
1029+ -- sb = split done
1030+
1031+ -- Caution! There is mutual recursion here, inlining the right functions is
1032+ -- important.
1033+
1034+ {-# INLINE handleSplitStep #-}
1035+ handleSplitStep cs sres =
1036+ case sres of
1037+ Partial ss1 -> return $ Partial $ Tuple' ss1 cs
1038+ Done sb -> runCollector cs sb
1039+
1040+ {-# INLINE handleCollectStep #-}
1041+ handleCollectStep cres =
1042+ case cres of
1043+ Partial cs -> do
1044+ sres <- sinitial
1045+ handleSplitStep cs sres
1046+ Done cb -> return $ Done cb
1047+
1048+ -- Do not inline this
1049+ runCollector cs sb = cstep cs sb >>= handleCollectStep
1050+
1051+ initial = cinitial >>= handleCollectStep
1052+
1053+ {-# INLINE step #-}
1054+ step (Tuple' ss cs) a = do
1055+ sres <- sstep ss a
1056+ handleSplitStep cs sres
1057+
1058+ extract (Tuple' ss cs) = do
1059+ sb <- sextract ss
1060+ cres <- cstep cs sb
1061+ case cres of
1062+ Partial s -> cextract s
1063+ Done b -> return b
1064+
10091065-- | @chunksOf n split collect@ repeatedly applies the @split@ fold to chunks
10101066-- of @n@ items in the input stream and supplies the result to the @collect@
10111067-- fold.