@@ -46,41 +46,70 @@
46module Streamly.Prelude
46module Streamly.Prelude
48 -- * Construction
48 -- * Construction
49+ -- | All other stream construction and generation combinators described
50+ -- later, and even more custom combinators can be expressed in terms of
51+ -- these primitives. However, the special versions provided in this module
52+ -- can be more efficient in some situations.
49− -- | Primitives to construct a stream.
55+ -- | Primitives to construct a stream from pure values or monadic actions.
56− -- * Deconstruction
64+ -- ** From Streams
57− , uncons
65+ -- | You can construct streams by appending or merging existing streams.
66+ -- When constructing streams from streams, '<>' and 'mempty' are the
67+ -- intuitive equivalents of 'K.cons' and 'K.nil', respectively. These
68+ -- primitives can be very useful when constructing your own custom stream
69+ -- combinators. Also see the variants of '<>' defined in the "Streamly"
70+ -- module. Note that appending streams is inexpensive, it is much more
71+ -- efficient than appending lists.
59 -- * Generation
73 -- * Generation
60− -- ** Unfolds
74+ -- ** Unfold and Iterate
75+ -- | Note that the generative steps of unfold and iterate are inherently
76+ -- serial as the next step depends on the result of the previous step.
77+ -- However, consumption of the result from the previous step can happen in
78+ -- parallel with the generation by the next step.
62 , unfoldrM
80 , unfoldrM
64− -- ** Specialized Generation
84+ -- ** Replicate and Repeat
65− -- | Generate a monadic stream from a seed.
85+ -- | Generate a monadic stream from a seed value or function. Note that
86+ -- these functions can generate a stream fully concurrently as, unlike
87+ -- unfolds, there is no dependency between steps, therefore, an unbounded
88+ -- number of steps can run concurrently. All of these can be expressed in
89+ -- terms of 'K.cons' and 'K.nil' primitives.
66 , replicateM
90 , replicateM
67 , K.repeat
91 , K.repeat
72− -- ** Conversions
94+ -- ** Generate From
73− -- | Transform an input structure into a stream.
95+ -- | Convert an input structure, container or source into a stream. All of
74− , yield
96+ -- these can be expressed in terms of primitives.
76 , fromList
97 , fromList
77 , fromListM
98 , fromListM
78 , K.fromFoldable
99 , K.fromFoldable
79 , fromFoldableM
100 , fromFoldableM
80 , fromHandle
101 , fromHandle
82 -- * Elimination
106 -- * Elimination
83 -- ** General Folds
108 -- ** General Folds
109+ -- | All the folds can be implemented in terms of 'uncons', however the
110+ -- specific implementations provided here are generally more efficient.
111+ -- Folds are inherently serial as each step needs to use the result of
112+ -- the previous step.
@@ -91,6 +120,8 @@ module Streamly.Prelude
93 -- ** Specialized Folds
122 -- ** Specialized Folds
123+ -- | These folds can be expressed in terms of the general fold routines but
124+ -- the special versions here can be more efficient in many cases.
95 -- Filtering folds: extract parts of the stream
126 -- Filtering folds: extract parts of the stream
@@ -118,27 +149,40 @@ module Streamly.Prelude
119 , product
150 , product
121− -- ** Map and Fold
152+ -- ** Fold To
125− -- | Transform a stream into an output structure of another type.
153+ -- | Convert or divert a stream into an output structure, container or
127 , toHandle
156 , toHandle
129 -- * Transformation
158 -- * Transformation
130− -- ** Mapping
159+ -- | One to one transformations, each element in the input stream is
131− , Serial.map
160+ -- transformed into a corresponding element in the output stream.
132− , mapM
161+ -- Therefore, the length of the stream and the ordering of elements in the
133− , sequence
162+ -- stream remains unchanged after the transformation.
135 -- ** Scanning
164 -- ** Scanning
136 -- | Scan is a transformation by continuously folding the result with the
165 -- | Scan is a transformation by continuously folding the result with the
137− -- next element of the stream.
166+ -- next element of the stream. This is the generalized way to transform a
167+ -- stream carrying state from previous transformation steps, other forms of
168+ -- transformation like map can be expressed in terms of this.
139 , scanlM'
170 , scanlM'
174+ -- | Map is a special form of scan where no state is carried from one step
182+ -- * Filtering and Insertion
183+ -- | Adding or removing elements from the stream thus changing the length
142 -- ** Filtering
186 -- ** Filtering
144 , filterM
188 , filterM
@@ -152,17 +196,21 @@ module Streamly.Prelude
152 -- ** Inserting
196 -- ** Inserting
153 , intersperseM
197 , intersperseM
155− -- ** Reordering
199+ -- * Reordering
156 , reverse
200 , reverse
158− -- ** Indices
202+ -- * Hybrid Operations
159− , findIndices
203+ -- ** Map and Fold
160− , elemIndices
204+ , mapM_
162 -- ** Map and Filter
206 -- ** Map and Filter
163 , mapMaybe
207 , mapMaybe
164 , mapMaybeM
208 , mapMaybeM
210+ -- ** Scan and filter
166 -- * Zipping
214 -- * Zipping
167 , zipWith
215 , zipWith
168 , zipWithM
216 , zipWithM
@@ -259,6 +307,15 @@ uncons m = K.uncons (K.adapt m)
259-- [0,1,2,3]
307-- [0,1,2,3]
310+-- unfoldr can be expressed in terms of 'yield' and '<>' as follows:
316+-- Just (a, b) -> 'yield' a '<>' (unfoldr step b)
262-- @since 0.1.0
319-- @since 0.1.0
263{-# INLINE_EARLY unfoldr #-}
320{-# INLINE_EARLY unfoldr #-}
264unfoldr :: (Monad m, IsStream t) => (b -> Maybe (a, b)) -> b -> t m a
321unfoldr :: (Monad m, IsStream t) => (b -> Maybe (a, b)) -> b -> t m a
@@ -310,13 +367,14 @@ unfoldrMSerial step seed = fromStreamS (S.unfoldrM step seed)
310-- Specialized Generation
367-- Specialized Generation
311------------------------------------------------------------------------------
368------------------------------------------------------------------------------
313−-- Faster than yieldM because there is no bind. Usually we can construct a
370+-- Faster than yieldM because there is no bind.
314−-- stream from a pure value using "pure" in an applicative, however in case of
315−-- Zip streams pure creates an infinite stream.
317−-- | Create a singleton stream from a pure value. In monadic streams, 'pure' or
372+-- | Create a singleton stream from a pure value. Same as @a `cons` nil@ but
373+-- slighly more efficient. Note that in monadic streams, 'yield' is the same
318−-- 'return' can be used in place of 'yield', however, in Zip applicative
374+-- as 'pure' or 'return', however, in Zip applicative streams it is not the
319−-- streams 'pure' is equivalent to 'repeat'.
375+-- same as 'pure' because in that case 'pure' is equivalent to 'repeat'
376+-- instead. In all other stream types, 'yield' is the same as @yieldM . pure@
377+-- but more efficient.
321-- @since 0.4.0
379-- @since 0.4.0
322{-# INLINE yield #-}
380{-# INLINE yield #-}
@@ -337,7 +395,8 @@ yield a = K.yield a
337yieldM :: (Monad m, IsStream t) => m a -> t m a
395yieldM :: (Monad m, IsStream t) => m a -> t m a
338yieldM m = K.yieldM m
396yieldM m = K.yieldM m
340−-- | Generate a stream by performing a monadic action @n@ times.
398+-- | Generate a stream by performing a monadic action @n@ times. Can be
399+-- expressed as @stimes n (yieldM m)@.
@@ -353,7 +412,8 @@ replicateM n m = go n
354 go cnt = if cnt <= 0 then K.nil else m |: go (cnt - 1)
413 go cnt = if cnt <= 0 then K.nil else m |: go (cnt - 1)
356−-- | Generate a stream by repeatedly executing a monadic action forever.
415+-- | Generate a stream by repeatedly executing a monadic action forever. Can be
416+-- expressed as @cycle1 . yieldM@.
359-- runStream $ serially $ S.take 10 $ S.repeatM $ (threadDelay 1000000 >> print 1)
419-- runStream $ serially $ S.take 10 $ S.repeatM $ (threadDelay 1000000 >> print 1)
@@ -405,8 +465,9 @@ iterateM step = go
405-- Conversions
465-- Conversions
406------------------------------------------------------------------------------
466------------------------------------------------------------------------------
408−-- | Construct a stream from a list containing pure values. This can be more
468+-- | Construct a stream from a list containing pure values. More efficient list
409−-- efficient than 'K.fromFoldable' for lists as it can fuse the list.
469+-- specific implementation of 'K.fromFoldable' as it works well with fusion
411-- @since 0.4.0
472-- @since 0.4.0
412{-# INLINE_EARLY fromList #-}
473{-# INLINE_EARLY fromList #-}
@@ -415,9 +476,9 @@ fromList = fromStreamS . S.fromList
415{-# RULES "fromList fallback to StreamK" [1]
476{-# RULES "fromList fallback to StreamK" [1]
416 forall a. S.toStreamK (S.fromList a) = K.fromFoldable a #-}
477 forall a. S.toStreamK (S.fromList a) = K.fromFoldable a #-}
418−-- | Construct a stream from a list containing monadic actions. This can be
479+-- | Construct a stream from a list containing monadic actions. More efficient
419−-- more efficient than 'fromFoldableM' especially for serial streams as it can
480+-- list specific implementation of 'fromFoldableM' especially for serial
420−-- fuse the list.
481+-- streams as it works well with fusion optimization.
422-- @since 0.4.0
483-- @since 0.4.0
423{-# INLINE_EARLY fromListM #-}
484{-# INLINE_EARLY fromListM #-}
@@ -426,7 +487,8 @@ fromListM = fromStreamD . D.fromListM
426{-# RULES "fromListM fallback to StreamK" [1]
487{-# RULES "fromListM fallback to StreamK" [1]
427 forall a. D.toStreamK (D.fromListM a) = fromFoldableM a #-}
488 forall a. D.toStreamK (D.fromListM a) = fromFoldableM a #-}
429−-- | Construct a stream from a 'Foldable' containing monadic actions.
490+-- | Construct a stream from a 'Foldable' containing monadic actions. Same as
491+-- @'Prelude.foldr' 'consM' 'K.nil'@.
432-- runStream $ serially $ S.fromFoldableM $ replicate 10 (threadDelay 1000000 >> print 1)
494-- runStream $ serially $ S.fromFoldableM $ replicate 10 (threadDelay 1000000 >> print 1)
@@ -687,7 +749,8 @@ lookup = K.lookup
687find :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe a)
749find :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe a)
688find = K.find
750find = K.find
690−-- | Finds all the indices of elements satisfying the given predicate.
752+-- | Find all the indices where the element in the stream satisfies the given
692-- @since 0.5.0
755-- @since 0.5.0
693{-# INLINE findIndices #-}
756{-# INLINE findIndices #-}
@@ -702,8 +765,8 @@ findIndices = K.findIndices
702findIndex :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe Int)
765findIndex :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe Int)
703findIndex p = head . findIndices p
766findIndex p = head . findIndices p
705−-- | Finds the index of all elements in the stream which are equal to the
768+-- | Find all the indices where the value of the element in the stream is equal
706−-- given.
769+-- to the given value.
708-- @since 0.5.0
771-- @since 0.5.0
709{-# INLINE elemIndices #-}
772{-# INLINE elemIndices #-}