@@ -125,11 +125,15 @@ import Prelude hiding (iterate, replicate, repeat)
128+-- >>> import Data.Function ((&))
128-- >>> import Prelude hiding (iterate, replicate, repeat)
129-- >>> import Prelude hiding (iterate, replicate, repeat)
129-- >>> import qualified Streamly.Prelude as Stream
130-- >>> import qualified Streamly.Prelude as Stream
130-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
131-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
131-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
132-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
132-- >>> import Control.Concurrent (threadDelay)
133-- >>> import Control.Concurrent (threadDelay)
134+-- >>> import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
136+-- >>> hSetBuffering stdout LineBuffering
134------------------------------------------------------------------------------
138------------------------------------------------------------------------------
135-- From Unfold
139-- From Unfold
@@ -159,29 +163,26 @@ unfold0 unf = unfold unf (error "unfold0: unexpected void evaluation")
159------------------------------------------------------------------------------
163------------------------------------------------------------------------------
163-- unfoldr step s =
167-- unfoldr step s =
164-- case step s of
168-- case step s of
165−-- Nothing -> 'K.nil'
169+-- Nothing -> Stream.nil
166−-- Just (a, b) -> a \`cons` unfoldr step b
170+-- Just (a, b) -> a `Stream.cons` unfoldr step b
169-- Build a stream by unfolding a /pure/ step function @step@ starting from a
173-- Build a stream by unfolding a /pure/ step function @step@ starting from a
170-- seed @s@. The step function returns the next element in the stream and the
174-- seed @s@. The step function returns the next element in the stream and the
171-- next seed value. When it is done it returns 'Nothing' and the stream ends.
175-- next seed value. When it is done it returns 'Nothing' and the stream ends.
172-- For example,
176-- For example,
176-- let f b =
179-- let f b =
177−-- if b > 3
180+-- if b > 2
178-- then Nothing
181-- then Nothing
179-- else Just (b, b + 1)
182-- else Just (b, b + 1)
180-- in Stream.toList $ Stream.unfoldr f 0
183-- in Stream.toList $ Stream.unfoldr f 0
182−-- [0,1,2,3]
185+-- [0,1,2]
186-- @since 0.1.0
187-- @since 0.1.0
187{-# INLINE_EARLY unfoldr #-}
188{-# INLINE_EARLY unfoldr #-}
@@ -195,26 +196,28 @@ unfoldr step seed = fromStreamS (S.unfoldr step seed)
195-- seed value. When it is done it returns 'Nothing' and the stream ends. For
196-- seed value. When it is done it returns 'Nothing' and the stream ends. For
196-- example,
197-- example,
200-- let f b =
200-- let f b =
201−-- if b > 3
201+-- if b > 2
202-- then return Nothing
202-- then return Nothing
203-- else return (Just (b, b + 1))
203-- else return (Just (b, b + 1))
204-- in Stream.toList $ Stream.unfoldrM f 0
204-- in Stream.toList $ Stream.unfoldrM f 0
206−-- [0,1,2,3]
206+-- [0,1,2]
209-- When run concurrently, the next unfold step can run concurrently with the
208-- When run concurrently, the next unfold step can run concurrently with the
210-- processing of the output of the previous step. Note that more than one step
209-- processing of the output of the previous step. Note that more than one step
211-- cannot run concurrently as the next step depends on the output of the
210-- cannot run concurrently as the next step depends on the output of the
212-- previous step.
211-- previous step.
215−-- (fromAsync $ S.unfoldrM (\\n -> liftIO (threadDelay 1000000) >> return (Just (n, n + 1))) 0)
214+-- let f b =
216−-- & S.foldlM' (\\_ a -> threadDelay 1000000 >> print a) ()
215+-- if b > 2
217−-- @
216+-- then return Nothing
217+-- else threadDelay 1000000 >> return (Just (b, b + 1))
218+-- in Stream.toList $ Stream.delay 1 $ Stream.fromAsync $ Stream.unfoldrM f 0
219-- /Concurrent/
222-- /Concurrent/
@@ -253,9 +256,7 @@ repeat :: (IsStream t, Monad m) => a -> t m a
253repeat = fromStreamS . S.repeat
256repeat = fromStreamS . S.repeat
257−-- replicate = take n . repeat
259+-- >>> replicate n = Stream.take n . Stream.repeat
260-- Generate a stream of length @n@ by repeating a value @n@ times.
261-- Generate a stream of length @n@ by repeating a value @n@ times.
@@ -265,16 +266,25 @@ replicate :: (IsStream t, Monad m) => Int -> a -> t m a
265replicate n = fromStreamS . S.replicate n
266replicate n = fromStreamS . S.replicate n
269−-- replicateM = take n . repeatM
269+-- >>> replicateM n = Stream.take n . Stream.repeatM
272-- Generate a stream by performing a monadic action @n@ times. Same as:
271-- Generate a stream by performing a monadic action @n@ times. Same as:
274−-- @
273+-- >>> pr n = threadDelay 1000000 >> print n
275+-- This runs serially and takes 3 seconds:
275−-- drain $ fromSerial $ S.replicateM 10 $ (threadDelay 1000000 >> print 1)
277+-- >>> Stream.drain $ Stream.fromSerial $ Stream.replicateM 3 $ pr 1
282+-- This runs concurrently and takes just 1 second:
276−-- drain $ fromAsync $ S.replicateM 10 $ (threadDelay 1000000 >> print 1)
284+-- >>> Stream.drain $ Stream.fromAsync $ Stream.replicateM 3 $ pr 1
279-- /Concurrent/
289-- /Concurrent/
@@ -398,10 +408,8 @@ timeout = undefined
398-- map. Check performance equivalence.
408-- map. Check performance equivalence.
402−-- fromIndices f = fmap f $ Stream.enumerateFrom 0
411+-- >>> fromIndices f = fmap f $ Stream.enumerateFrom 0
403−-- fromIndices f = let g i = f i \`cons` g (i + 1) in g 0
412+-- >>> fromIndices f = let g i = f i `Stream.cons` g (i + 1) in g 0
406-- Generate an infinite stream, whose values are the output of a function @f@
414-- Generate an infinite stream, whose values are the output of a function @f@
407-- applied on the corresponding index. Index starts at 0.
415-- applied on the corresponding index. Index starts at 0.
@@ -416,10 +424,8 @@ fromIndices = fromStreamS . S.fromIndices
420−-- fromIndicesM f = Stream.mapM f $ Stream.enumerateFrom 0
427+-- >>> fromIndicesM f = Stream.mapM f $ Stream.enumerateFrom 0
421−-- fromIndicesM f = let g i = f i \`consM` g (i + 1) in g 0
428+-- >>> fromIndicesM f = let g i = f i `Stream.consM` g (i + 1) in g 0
424-- Generate an infinite stream, whose values are the output of a monadic
430-- Generate an infinite stream, whose values are the output of a monadic
425-- function @f@ applied on the corresponding index. Index starts at 0.
431-- function @f@ applied on the corresponding index. Index starts at 0.
@@ -442,46 +448,54 @@ fromIndicesMSerial = fromStreamS . S.fromIndicesM
442------------------------------------------------------------------------------
448------------------------------------------------------------------------------
446−-- iterate f x = x \`cons` iterate f x
451+-- >>> iterate f x = x `Stream.cons` iterate f x
449-- Generate an infinite stream with @x@ as the first element and each
453-- Generate an infinite stream with @x@ as the first element and each
450-- successive element derived by applying the function @f@ on the previous
454-- successive element derived by applying the function @f@ on the previous
451-- element.
455-- element.
454-- >>> Stream.toList $ Stream.take 5 $ Stream.iterate (+1) 1
457-- >>> Stream.toList $ Stream.take 5 $ Stream.iterate (+1) 1
455-- [1,2,3,4,5]
458-- [1,2,3,4,5]
459-- @since 0.1.2
460-- @since 0.1.2
460{-# INLINE_NORMAL iterate #-}
461{-# INLINE_NORMAL iterate #-}
461iterate :: (IsStream t, Monad m) => (a -> a) -> a -> t m a
462iterate :: (IsStream t, Monad m) => (a -> a) -> a -> t m a
462iterate step = fromStreamS . S.iterate step
463iterate step = fromStreamS . S.iterate step
466−-- iterateM f m = m >>= \a -> return a \`consM` iterateM f (f a)
466+-- >>> iterateM f m = m >>= \a -> return a `Stream.consM` iterateM f (f a)
469-- Generate an infinite stream with the first element generated by the action
468-- Generate an infinite stream with the first element generated by the action
470-- @m@ and each successive element derived by applying the monadic function
469-- @m@ and each successive element derived by applying the monadic function
471-- @f@ on the previous element.
470-- @f@ on the previous element.
472+-- >>> pr n = threadDelay 1000000 >> print n
474+-- Stream.iterateM (\x -> pr x >> return (x + 1)) (return 0)
476+-- & Stream.fromSerial
473-- When run concurrently, the next iteration can run concurrently with the
483-- When run concurrently, the next iteration can run concurrently with the
474-- processing of the previous iteration. Note that more than one iteration
484-- processing of the previous iteration. Note that more than one iteration
475-- cannot run concurrently as the next iteration depends on the output of the
485-- cannot run concurrently as the next iteration depends on the output of the
476-- previous iteration.
486-- previous iteration.
479−-- drain $ fromSerial $ S.take 10 $ S.iterateM
480−-- (\\x -> threadDelay 1000000 >> print x >> return (x + 1)) (return 0)
489+-- Stream.iterateM (\x -> pr x >> return (x + 1)) (return 0)
481−--
490+-- & Stream.delay 1
482−-- drain $ fromAsync $ S.take 10 $ S.iterateM
492+-- & Stream.fromAsync
483−-- (\\x -> threadDelay 1000000 >> print x >> return (x + 1)) (return 0)
493+-- & Stream.toList
486-- /Concurrent/
500-- /Concurrent/
@@ -505,13 +519,12 @@ iterateMSerial step = fromStreamS . S.iterateM step
506-- The function @fix@ defined as:
520-- The function @fix@ defined as:
508−-- > fix f = let x = f x in x
522+-- >>> fix f = let x = f x in x
510-- ensures that the argument of a function and its output refer to the same
524-- ensures that the argument of a function and its output refer to the same
511-- lazy value @x@ i.e. the same location in memory. Thus @x@ can be defined
525-- lazy value @x@ i.e. the same location in memory. Thus @x@ can be defined
512-- in terms of itself, creating structures with cyclic references.
526-- in terms of itself, creating structures with cyclic references.
514−-- >>> import Data.Function (fix)
515-- >>> f ~(a, b) = ([1, b], head a)
528-- >>> f ~(a, b) = ([1, b], head a)
516-- >>> fix f
529-- >>> fix f
517-- ([1,1],1)
530-- ([1,1],1)
@@ -529,21 +542,18 @@ iterateMSerial step = fromStreamS . S.iterateM step
529-- represents the tuple @(x,y)@ returned by it in a given iteration. We define
542-- represents the tuple @(x,y)@ returned by it in a given iteration. We define
530-- the first element of the tuple in terms of the second.
543-- the first element of the tuple in terms of the second.
533−-- import Streamly.Internal.Data.Stream.IsStream as Stream
545+-- >>> import Streamly.Internal.Data.Stream.IsStream as Stream
534−-- import System.IO.Unsafe (unsafeInterleaveIO)
546+-- >>> import System.IO.Unsafe (unsafeInterleaveIO)
537−-- Stream.mapM_ print $ Stream.mfix f
549+-- main = Stream.mapM_ print $ Stream.mfix f
541-- f action = do
551-- f action = do
542-- let incr n act = fmap ((+n) . snd) $ unsafeInterleaveIO act
552-- let incr n act = fmap ((+n) . snd) $ unsafeInterleaveIO act
543-- x <- Stream.fromListM [incr 1 action, incr 2 action]
553-- x <- Stream.fromListM [incr 1 action, incr 2 action]
544-- y <- Stream.fromList [4,5]
554-- y <- Stream.fromList [4,5]
545-- return (x, y)
555-- return (x, y)
548-- Note: you cannot achieve this by just changing the order of the monad
558-- Note: you cannot achieve this by just changing the order of the monad
549-- statements because that would change the order in which the stream elements
559-- statements because that would change the order in which the stream elements
@@ -562,9 +572,7 @@ mfix f = fromStream $ K.mfix (toStream . f)
562------------------------------------------------------------------------------
572------------------------------------------------------------------------------
566−-- fromFoldable = 'Prelude.foldr' 'cons' 'nil'
575+-- >>> fromFoldable = Prelude.foldr Stream.cons Stream.nil
569-- Construct a stream from a 'Foldable' containing pure values:
577-- Construct a stream from a 'Foldable' containing pure values:
@@ -574,16 +582,20 @@ fromFoldable :: (IsStream t, Foldable f) => f a -> t m a
574fromFoldable = fromStream . K.fromFoldable
582fromFoldable = fromStream . K.fromFoldable
578−-- fromFoldableM = 'Prelude.foldr' 'consM' 'K.nil'
585+-- >>> fromFoldableM = Prelude.foldr Stream.consM Stream.nil
581-- Construct a stream from a 'Foldable' containing monadic actions.
587-- Construct a stream from a 'Foldable' containing monadic actions.
583−-- @
589+-- >>> pr n = threadDelay 1000000 >> print n
584−-- drain $ fromSerial $ S.fromFoldableM $ replicateM 10 (threadDelay 1000000 >> print 1)
590+-- >>> Stream.drain $ Stream.fromSerial $ Stream.fromFoldableM $ map pr [1,2,3]
585−-- drain $ fromAsync $ S.fromFoldableM $ replicateM 10 (threadDelay 1000000 >> print 1)
595+-- >>> Stream.drain $ Stream.fromAsync $ Stream.fromFoldableM $ map pr [1,2,3]
588-- /Concurrent (do not use with 'fromParallel' on infinite containers)/
600-- /Concurrent (do not use with 'fromParallel' on infinite containers)/
@@ -593,9 +605,10 @@ fromFoldableM :: (IsStream t, MonadAsync m, Foldable f) => f (m a) -> t m a
593fromFoldableM = Prelude.foldr consM IsStream.nil
605fromFoldableM = Prelude.foldr consM IsStream.nil
596−-- @
608+-- >>> fromListM = Stream.fromFoldableM
609+-- >>> fromListM = Stream.sequence . Stream.fromList
610+-- >>> fromListM = Stream.mapM id . Stream.fromList
597−-- fromListM = 'Prelude.foldr' 'K.consM' 'K.nil'
611+-- >>> fromListM = Prelude.foldr Stream.consM Stream.nil
600-- Construct a stream from a list of monadic actions. This is more efficient
613-- Construct a stream from a list of monadic actions. This is more efficient
601-- than 'fromFoldableM' for serial streams.
614-- than 'fromFoldableM' for serial streams.