on master help sign in
update documentation
092ecb9Harendra Kumar
src/Streamly/Prelude.hs+53−7
@@ -26,8 +26,9 @@
26-- provided for convenience and for consistency with other pure APIs in the
26-- provided for convenience and for consistency with other pure APIs in the
27-- @base@ package.
27-- @base@ package.
28--
28--
29−-- Functions having a 'MonadAsync' constraint work concurrently when used
29+-- Functions having a 'MonadAsync' constraint work concurrently when used with
30−-- with appropriate stream type combinator.
30+-- appropriate stream type combinator. Please be careful to not use 'parallely'
31+-- with infinite streams.
31--
32--
32-- Deconstruction and folds accept a 'SerialT' type instead of a polymorphic
33-- Deconstruction and folds accept a 'SerialT' type instead of a polymorphic
33-- type to ensure that streams always have a concrete monomorphic type by
34-- type to ensure that streams always have a concrete monomorphic type by
@@ -45,7 +46,7 @@ module Streamly.Prelude
45 , cons
46 , cons
46 , (.:)
47 , (.:)
47
48
48− -- * General Unfold
49+ -- * Generation by Unfolding
49 , unfoldr
50 , unfoldr
50 , unfoldrM
51 , unfoldrM
51
52
@@ -63,7 +64,7 @@ module Streamly.Prelude
63 -- * Deconstruction
64 -- * Deconstruction
64 , uncons
65 , uncons
65
66
66− -- * Folding
67+ -- * Elimination by Folding
67 -- ** General Folds
68 -- ** General Folds
68 , foldr
69 , foldr
69 , foldrM
70 , foldrM
@@ -146,7 +147,21 @@ import Streamly.Streams
146-- Construction
147-- Construction
147------------------------------------------------------------------------------
148------------------------------------------------------------------------------
148
149
149−-- | Build a Stream by unfolding pure steps starting from a seed.
150+-- | Build a stream by unfolding a /pure/ step function starting from a seed.
151+-- The step function returns the next element in the stream and the next seed
152+-- value. When it is done it returns 'Nothing' and the stream ends. For
153+-- example,
154+--
155+-- @
156+-- let f b =
157+-- if b > 3
158+-- then Nothing
159+-- else Just (b, b + 1)
160+-- in toList $ unfoldr f 0
161+-- @
162+-- @
163+-- [0,1,2,3]
164+-- @
150--
165--
151-- @since 0.1.0
166-- @since 0.1.0
152{-# INLINE unfoldr #-}
167{-# INLINE unfoldr #-}
@@ -158,9 +173,28 @@ unfoldr step = fromStream . go
158 Nothing -> stp
173 Nothing -> stp
159 Just (a, b) -> yld a (go b)
174 Just (a, b) -> yld a (go b)
160
175
161−-- | Build a Stream by unfolding monadic steps starting from a seed.
176+-- | Build a stream by unfolding a /monadic/ step function starting from a
177+-- seed. The step function returns the next element in the stream and the next
178+-- seed value. When it is done it returns 'Nothing' and the stream ends. For
179+-- example,
162--
180--
163−-- @since 0.1.0
181+-- @
182+-- let f b =
183+-- if b > 3
184+-- then return Nothing
185+-- else print b >> return (Just (b, b + 1))
186+-- in runStream $ unfoldrM f 0
187+-- @
188+-- @
189+-- 0
190+-- 1
191+-- 2
192+-- 3
193+-- @
194+--
195+-- /Concurrent/
196+--
197+-- /Since: 0.1.0/
164{-# INLINE unfoldrM #-}
198{-# INLINE unfoldrM #-}
165unfoldrM :: (IsStream t, MonadAsync m) => (b -> m (Maybe (a, b))) -> b -> t m a
199unfoldrM :: (IsStream t, MonadAsync m) => (b -> m (Maybe (a, b))) -> b -> t m a
166unfoldrM step = go
200unfoldrM step = go
@@ -181,6 +215,8 @@ fromFoldable = Prelude.foldr cons nil
181
215
182-- | Construct a stream from a 'Foldable' containing monadic actions.
216-- | Construct a stream from a 'Foldable' containing monadic actions.
183--
217--
218+-- /Concurrent (do not use with 'parallely' on infinite containers)/
219+--
184-- @since 0.3.0
220-- @since 0.3.0
185{-# INLINE fromFoldableM #-}
221{-# INLINE fromFoldableM #-}
186fromFoldableM :: (IsStream t, MonadAsync m, Foldable f) => f (m a) -> t m a
222fromFoldableM :: (IsStream t, MonadAsync m, Foldable f) => f (m a) -> t m a
@@ -209,6 +245,8 @@ once = fromStream . S.once
209
245
210-- | Generate a stream by performing a monadic action @n@ times.
246-- | Generate a stream by performing a monadic action @n@ times.
211--
247--
248+-- /Concurrent/
249+--
212-- @since 0.1.1
250-- @since 0.1.1
213replicateM :: (IsStream t, MonadAsync m) => Int -> m a -> t m a
251replicateM :: (IsStream t, MonadAsync m) => Int -> m a -> t m a
214replicateM n m = go n
252replicateM n m = go n
@@ -217,6 +255,8 @@ replicateM n m = go n
217
255
218-- | Generate a stream by repeatedly executing a monadic action forever.
256-- | Generate a stream by repeatedly executing a monadic action forever.
219--
257--
258+-- /Concurrent, infinite (do not use with 'parallely')/
259+--
220-- @since 0.2.0
260-- @since 0.2.0
221repeatM :: (IsStream t, MonadAsync m) => m a -> t m a
261repeatM :: (IsStream t, MonadAsync m) => m a -> t m a
222repeatM = go
262repeatM = go
@@ -233,6 +273,8 @@ iterate step = fromStream . go
233-- | Iterate a monadic function from a seed value, streaming the results
273-- | Iterate a monadic function from a seed value, streaming the results
234-- forever.
274-- forever.
235--
275--
276+-- /Concurrent, infinite (do not use with 'parallely')/
277+--
236-- @since 0.1.2
278-- @since 0.1.2
237iterateM :: (IsStream t, MonadAsync m) => (a -> m a) -> a -> t m a
279iterateM :: (IsStream t, MonadAsync m) => (a -> m a) -> a -> t m a
238iterateM step = go
280iterateM step = go
@@ -657,6 +699,8 @@ maximum m = go Nothing (toStream m)
657-- | Replace each element of the stream with the result of a monadic action
699-- | Replace each element of the stream with the result of a monadic action
658-- applied on the element.
700-- applied on the element.
659--
701--
702+-- /Concurrent (do not use with 'parallely' on infinite streams)/
703+--
660-- @since 0.1.0
704-- @since 0.1.0
661{-# INLINE mapM #-}
705{-# INLINE mapM #-}
662mapM :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m b
706mapM :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m b
@@ -684,6 +728,8 @@ mapM_ f m = go (toStream m)
684-- | Reduce a stream of monadic actions to a stream of the output of those
728-- | Reduce a stream of monadic actions to a stream of the output of those
685-- actions.
729-- actions.
686--
730--
731+-- /Concurrent (do not use with 'parallely' on infinite streams)/
732+--
687-- @since 0.1.0
733-- @since 0.1.0
688sequence :: (IsStream t, MonadAsync m) => t m (m a) -> t m a
734sequence :: (IsStream t, MonadAsync m) => t m (m a) -> t m a
689sequence m = go (toStream m)
735sequence m = go (toStream m)
src/Streamly/Streams.hs+4
@@ -141,6 +141,8 @@ class IsStream t where
141 -- ["hello","world"]
141 -- ["hello","world"]
142 -- @
142 -- @
143 --
143 --
144+ -- /Concurrent (do not use 'parallely' to construct infinite streams)/
145+ --
144 -- @since 0.2.0
146 -- @since 0.2.0
145 consM :: MonadAsync m => m a -> t m a -> t m a
147 consM :: MonadAsync m => m a -> t m a -> t m a
146 -- | Operator equivalent of 'consM'.
148 -- | Operator equivalent of 'consM'.
@@ -152,6 +154,8 @@ class IsStream t where
152 -- ["hello","world"]
154 -- ["hello","world"]
153 -- @
155 -- @
154 --
156 --
157+ -- /Concurrent (do not use 'parallely' to construct infinite streams)/
158+ --
155 -- @since 0.2.0
159 -- @since 0.2.0
156 (|:) :: MonadAsync m => m a -> t m a -> t m a
160 (|:) :: MonadAsync m => m a -> t m a -> t m a
157
161
src/Streamly/Tutorial.hs+16
@@ -40,6 +40,9 @@ module Streamly.Tutorial
40 -- * Flavors of Streams
40 -- * Flavors of Streams
41 -- $flavors
41 -- $flavors
42
42
43+ -- * Writing Concurrent Programs
44+ -- $programs
45+
43 -- * Imports and Supporting Code
46 -- * Imports and Supporting Code
44 -- $imports
47 -- $imports
45
48
@@ -231,6 +234,19 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
231-- or 'zipAsyncly'. The default stream type is inferred as 'Serial' unless you
234-- or 'zipAsyncly'. The default stream type is inferred as 'Serial' unless you
232-- change it by using one of the combinators or using a type annotation.
235-- change it by using one of the combinators or using a type annotation.
233
236
237+-- $programs
238+--
239+-- When writing concurrent programs it is advised to not use the concurrent
240+-- style stream combinators blindly at the top level. That might create too
241+-- much concurrency where it is not even required and therefore degrade
242+-- performance. Please be aware of what all APIs that you have used may become
243+-- concurrent when you use a concurrency combinator. For example if you have a
244+-- 'repeatM' somewhere in your program and you use 'parallely' on top, the
245+-- 'repeatM' becomes fully parallel, resulting into an infinite parallel
246+-- execution . Instead start with a default serial program and add concurrent
247+-- combinators where necessary, and use the 'serially' combinator to suppress
248+-- unnecessary concurrency.
249+
234-- $monadtransformers
250-- $monadtransformers
235--
251--
236-- To represent streams in an arbitrary monad use the more general monad
252-- To represent streams in an arbitrary monad use the more general monad