@@ -46,41 +46,70 @@
4646module Streamly.Prelude
4747 (
4848 -- * Construction
49− -- | Primitives to construct a stream.
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.
53+
54+ -- ** From Elements
55+ -- | Primitives to construct a stream from pure values or monadic actions.
5056 K.nil
5157 , K.cons
5258 , (K..:)
5359 , consM
5460 , (|:)
61+ , yield
62+ , yieldM
5563
56− -- * Deconstruction
57− , uncons
64+ -- ** From Streams
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.
5872
5973 -- * 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.
6179 , unfoldr
6280 , unfoldrM
81+ , iterate
82+ , iterateM
6383
64− -- ** Specialized Generation
65− -- | Generate a monadic stream from a seed.
84+ -- ** Replicate and Repeat
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.
6690 , replicateM
6791 , K.repeat
6892 , repeatM
69− , iterate
70− , iterateM
7193
72− -- ** Conversions
73− -- | Transform an input structure into a stream.
74− , yield
75− , yieldM
94+ -- ** Generate From
95+ -- | Convert an input structure, container or source into a stream. All of
96+ -- these can be expressed in terms of primitives.
7697 , fromList
7798 , fromListM
7899 , K.fromFoldable
79100 , fromFoldableM
80101 , fromHandle
81102
103+ -- * Deconstruction
104+ , uncons
105+
82106 -- * Elimination
107+
83108 -- ** 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.
84113 , foldr
85114 , foldr1
86115 , foldrM
@@ -91,6 +120,8 @@ module Streamly.Prelude
91120 , foldxM
92121
93122 -- ** 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.
94125
95126 -- Filtering folds: extract parts of the stream
96127 , head
@@ -118,27 +149,40 @@ module Streamly.Prelude
118149 , sum
119150 , product
120151
121− -- ** Map and Fold
122− , mapM_
123−
124− -- ** Conversions
125− -- | Transform a stream into an output structure of another type.
152+ -- ** Fold To
153+ -- | Convert or divert a stream into an output structure, container or
154+ -- sink.
126155 , toList
127156 , toHandle
128157
129158 -- * Transformation
130− -- ** Mapping
131− , Serial.map
132− , mapM
133− , sequence
159+ -- | One to one transformations, each element in the input stream is
160+ -- transformed into a corresponding element in the output stream.
161+ -- Therefore, the length of the stream and the ordering of elements in the
162+ -- stream remains unchanged after the transformation.
134163
135164 -- ** Scanning
136165 -- | 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.
138169 , scanl'
139170 , scanlM'
140171 , scanx
141172
173+ -- ** Mapping
174+ -- | Map is a special form of scan where no state is carried from one step
175+ -- to the next.
176+ , Serial.map
177+ , mapM
178+
179+ -- ** Flattening
180+ , sequence
181+
182+ -- * Filtering and Insertion
183+ -- | Adding or removing elements from the stream thus changing the length
184+ -- of the stream.
185+
142186 -- ** Filtering
143187 , filter
144188 , filterM
@@ -152,17 +196,21 @@ module Streamly.Prelude
152196 -- ** Inserting
153197 , intersperseM
154198
155− -- ** Reordering
199+ -- * Reordering
156200 , reverse
157201
158− -- ** Indices
159− , findIndices
160− , elemIndices
202+ -- * Hybrid Operations
203+ -- ** Map and Fold
204+ , mapM_
161205
162206 -- ** Map and Filter
163207 , mapMaybe
164208 , mapMaybeM
165209
210+ -- ** Scan and filter
211+ , findIndices
212+ , elemIndices
213+
166214 -- * Zipping
167215 , zipWith
168216 , zipWithM
@@ -259,6 +307,15 @@ uncons m = K.uncons (K.adapt m)
259307-- [0,1,2,3]
260308-- @
261309--
310+-- unfoldr can be expressed in terms of 'yield' and '<>' as follows:
311+--
312+-- @
313+-- unfoldr step s =
314+-- case step s of
315+-- Nothing -> mempty
316+-- Just (a, b) -> 'yield' a '<>' (unfoldr step b)
317+-- @
318+--
262319-- @since 0.1.0
263320{-# INLINE_EARLY unfoldr #-}
264321unfoldr :: (Monad m, IsStream t) => (b -> Maybe (a, b)) -> b -> t m a
@@ -310,13 +367,14 @@ unfoldrMSerial step seed = fromStreamS (S.unfoldrM step seed)
310367-- Specialized Generation
311368------------------------------------------------------------------------------
312369
313−-- Faster than yieldM because there is no bind. Usually we can construct a
314−-- stream from a pure value using "pure" in an applicative, however in case of
315−-- Zip streams pure creates an infinite stream.
370+-- Faster than yieldM because there is no bind.
316371--
317−-- | Create a singleton stream from a pure value. In monadic streams, 'pure' or
318−-- 'return' can be used in place of 'yield', however, in Zip applicative
319−-- streams 'pure' is equivalent to 'repeat'.
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
374+-- as 'pure' or 'return', however, in Zip applicative streams it is not the
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.
320378--
321379-- @since 0.4.0
322380{-# INLINE yield #-}
@@ -337,7 +395,8 @@ yield a = K.yield a
337395yieldM :: (Monad m, IsStream t) => m a -> t m a
338396yieldM m = K.yieldM m
339397
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)@.
341400--
342401--
343402-- @
@@ -353,7 +412,8 @@ replicateM n m = go n
353412 where
354413 go cnt = if cnt <= 0 then K.nil else m |: go (cnt - 1)
355414
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@.
357417--
358418-- @
359419-- runStream $ serially $ S.take 10 $ S.repeatM $ (threadDelay 1000000 >> print 1)
@@ -405,8 +465,9 @@ iterateM step = go
405465-- Conversions
406466------------------------------------------------------------------------------
407467
408−-- | Construct a stream from a list containing pure values. This can be more
409−-- efficient than 'K.fromFoldable' for lists as it can fuse the list.
468+-- | Construct a stream from a list containing pure values. More efficient list
469+-- specific implementation of 'K.fromFoldable' as it works well with fusion
470+-- optimization.
410471--
411472-- @since 0.4.0
412473{-# INLINE_EARLY fromList #-}
@@ -415,9 +476,9 @@ fromList = fromStreamS . S.fromList
415476{-# RULES "fromList fallback to StreamK" [1]
416477 forall a. S.toStreamK (S.fromList a) = K.fromFoldable a #-}
417478
418−-- | Construct a stream from a list containing monadic actions. This can be
419−-- more efficient than 'fromFoldableM' especially for serial streams as it can
420−-- fuse the list.
479+-- | Construct a stream from a list containing monadic actions. More efficient
480+-- list specific implementation of 'fromFoldableM' especially for serial
481+-- streams as it works well with fusion optimization.
421482--
422483-- @since 0.4.0
423484{-# INLINE_EARLY fromListM #-}
@@ -426,7 +487,8 @@ fromListM = fromStreamD . D.fromListM
426487{-# RULES "fromListM fallback to StreamK" [1]
427488 forall a. D.toStreamK (D.fromListM a) = fromFoldableM a #-}
428489
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'@.
430492--
431493-- @
432494-- runStream $ serially $ S.fromFoldableM $ replicate 10 (threadDelay 1000000 >> print 1)
@@ -687,7 +749,8 @@ lookup = K.lookup
687749find :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe a)
688750find = K.find
689751
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
753+-- predicate.
691754--
692755-- @since 0.5.0
693756{-# INLINE findIndices #-}
@@ -702,8 +765,8 @@ findIndices = K.findIndices
702765findIndex :: Monad m => (a -> Bool) -> SerialT m a -> m (Maybe Int)
703766findIndex p = head . findIndices p
704767
705−-- | Finds the index of all elements in the stream which are equal to the
706−-- given.
768+-- | Find all the indices where the value of the element in the stream is equal
769+-- to the given value.
707770--
708771-- @since 0.5.0
709772{-# INLINE elemIndices #-}