@@ -23,22 +23,36 @@ module Streamly.Internal.Data.Consumer.Type
23 -- * Types
23 -- * Types
24 Consumer (..)
24 Consumer (..)
26− -- Combinators
26+ -- * Constructors
30− -- Consumers
29+ -- * Consumers
36import Control.Monad ((>=>))
41import Control.Monad ((>=>))
42+#if __GLASGOW_HASKELL__ < 804
43+import Data.Semigroup (Semigroup((<>)))
37import Fusion.Plugin.Types (Fuse(..))
45import Fusion.Plugin.Types (Fuse(..))
38import Streamly.Internal.Data.Fold.Step (Step(..), mapMStep)
46import Streamly.Internal.Data.Fold.Step (Step(..), mapMStep)
40import Prelude hiding (take)
48import Prelude hiding (take)
52+-- >>> import qualified Streamly.Internal.Data.Consumer.Type as Consumer
53+-- >>> import qualified Streamly.Internal.Data.Fold.Type as Fold
54+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
42-- All folds in the Fold module should be implemented using Consumers.
56-- All folds in the Fold module should be implemented using Consumers.
44-- | Like 'Fold' except that the initial state of the accmulator can be
58-- | Like 'Fold' except that the initial state of the accmulator can be
@@ -51,6 +65,27 @@ data Consumer m c a b =
51 -- | @Fold @ @ step @ @ inject @ @ extract@
65 -- | @Fold @ @ step @ @ inject @ @ extract@
52 forall s. Consumer (s -> a -> m (Step s b)) (c -> m (Step s b)) (s -> m b)
66 forall s. Consumer (s -> a -> m (Step s b)) (c -> m (Step s b)) (s -> m b)
68+------------------------------------------------------------------------------
69+-- Left fold constructors
70+------------------------------------------------------------------------------
72+-- | Make a consumer from a left fold style pure step function.
74+-- If your 'Fold' returns only 'Partial' (i.e. never returns a 'Done') then you
75+-- can use @foldl'*@ constructors.
77+-- See also: @Streamly.Prelude.foldl'@
82+foldl' :: Monad m => (b -> a -> b) -> Consumer m b a b
85+ (\s a -> return $ Partial $ step s a)
54------------------------------------------------------------------------------
89------------------------------------------------------------------------------
55-- Mapping on input
90-- Mapping on input
56------------------------------------------------------------------------------
91------------------------------------------------------------------------------
@@ -101,6 +136,27 @@ drainBy f = Consumer step inject extract
102 extract _ = return ()
137 extract _ = return ()
139+------------------------------------------------------------------------------
141+------------------------------------------------------------------------------
143+-- | Append the elements of an input stream to a provided starting value.
145+-- >>> stream = Stream.map Data.Monoid.Sum $ Stream.enumerateFromTo 1 10
146+-- >>> Stream.fold (Fold.fromConsumer Consumer.sconcat 10) stream
149+-- >>> sconcat = Consumer.foldl' (<>)
152+{-# INLINE sconcat #-}
153+sconcat :: (Monad m, Semigroup a) => Consumer m a a a
154+sconcat = foldl' (<>)
156+------------------------------------------------------------------------------
158+------------------------------------------------------------------------------
104-- Required to fuse "take" with "many" in "chunksOf", for ghc-9.x
160-- Required to fuse "take" with "many" in "chunksOf", for ghc-9.x
105{-# ANN type Tuple'Fused Fuse #-}
161{-# ANN type Tuple'Fused Fuse #-}
106data Tuple'Fused a b = Tuple'Fused !a !b deriving Show
162data Tuple'Fused a b = Tuple'Fused !a !b deriving Show