on master help sign in
Update and reorganize the prelude API docs
commit1c9e94809f63f80062747b12b474790cfa291a61 authorHarendra Kumar <harendra.kumar@gmail.com> dateMon 17 Sep 2018, 17:01 (8 years ago) parent8c07d96
3 files changed+111−45
README.md+2−1 src/Streamly/Prelude.hs+106−43 src/Streamly/Streams/StreamK.hs+3−1
README.md+2−1
@@ -41,7 +41,8 @@ We can say that streamly is a superset of lists and IO, with builtin
4141concurrency. If you want to write a program that involves IO, concurrent or
4242not, then you can just use streamly as the base monad, heck, you could even use
4343streamly for pure computations, as streamly performs at par with pure lists or
44−`vector`.
44+`vector`. In fact, streamly is better than lists because it appends much
45+faster than lists, you do not need difference lists for that.
4546
4647If you need convincing for using streaming or data flow programming paradigm
4748itself then try to answer this question - why do we use lists? It boils down to
src/Streamly/Prelude.hs+106−43
@@ -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 #-}
src/Streamly/Streams/StreamK.hs+3−1
@@ -412,6 +412,7 @@ once :: (Monad m, IsStream t) => m a -> t m a
412412once = yieldM
413413
414414-- | Generate an infinite stream by repeating a pure value.
415+-- Can be expressed as @cycle1 . yield@.
415416--
416417-- @since 0.4.0
417418repeat :: IsStream t => a -> t m a
@@ -421,7 +422,8 @@ repeat a = let x = cons a x in x
421422-- Conversions
422423-------------------------------------------------------------------------------
423424
424−-- | Construct a stream from a 'Foldable' containing pure values.
425+-- | Construct a stream from a 'Foldable' containing pure values. Same as
426+-- @'Prelude.foldr' 'cons' 'nil'@.
425427--
426428-- @since 0.2.0
427429{-# INLINE fromFoldable #-}