on master help sign in
Data.Stream: Update docs, expose doctest setup
fe3609bHarendra Kumar
core/src/DocTestDataStream.hsnew file+37
@@ -0,0 +1,37 @@
1+{- $setup
2+
3+>>> :m
4+>>> import Control.Concurrent (threadDelay)
5+>>> import Control.Monad (void)
6+>>> import Control.Monad.IO.Class (MonadIO (liftIO))
7+>>> import Control.Monad.Trans.Class (lift)
8+>>> import Control.Monad.Trans.Identity (runIdentityT)
9+>>> import Data.Either (fromLeft, fromRight, isLeft, isRight, either)
10+>>> import Data.Maybe (fromJust, isJust)
11+>>> import Data.Function (fix, (&))
12+>>> import Data.Functor.Identity (runIdentity)
13+>>> import Data.IORef
14+>>> import Data.Semigroup (cycle1)
15+>>> import GHC.Exts (Ptr (Ptr))
16+>>> import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
17+
18+>>> hSetBuffering stdout LineBuffering
19+>>> effect n = print n >> return n
20+
21+>>> import Streamly.Data.Stream (Stream)
22+>>> import qualified Streamly.Data.Array as Array
23+>>> import qualified Streamly.Data.Fold as Fold
24+>>> import qualified Streamly.Data.Stream as Stream
25+>>> import qualified Streamly.Data.Unfold as Unfold
26+>>> import qualified Streamly.Data.Parser as Parser
27+>>> import qualified Streamly.FileSystem.Dir as Dir
28+
29+For APIs that have not been released yet.
30+
31+>>> import qualified Streamly.Internal.Data.Fold as Fold
32+>>> import qualified Streamly.Internal.Data.Fold.Window as Window
33+>>> import qualified Streamly.Internal.Data.Parser as Parser
34+>>> import qualified Streamly.Internal.Data.Stream as Stream
35+>>> import qualified Streamly.Internal.Data.Unfold as Unfold
36+>>> import qualified Streamly.Internal.FileSystem.Dir as Dir
37+-}
core/src/Streamly/Data/Stream.hs+83−75
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Data.Stream
3-- Module : Streamly.Data.Stream
3-- Copyright : (c) 2017 Composewell Technologies
4-- Copyright : (c) 2017 Composewell Technologies
@@ -7,87 +8,29 @@
7-- Stability : released
8-- Stability : released
8-- Portability : GHC
9-- Portability : GHC
9--
10--
10−-- To run examples in this module:
11+-- Fast, composable stream producers with ability to terminate, supporting
12+-- stream fusion.
11--
13--
12−-- >>> import qualified Streamly.Data.Fold as Fold
14+-- Please refer to "Streamly.Internal.Data.Stream" for more functions that have
13−-- >>> import qualified Streamly.Data.Stream as Stream
15+-- not yet been released.
14--
16--
15−-- We will add some more imports in the examples as needed.
16−--
17−-- For effectful streams we will use the following IO action:
18−--
19−-- >>> effect n = print n >> return n
20−--
21−-- = Overview
22−--
23−-- Streamly is a framework for modular data flow based programming and
24−-- declarative concurrency. Powerful stream fusion framework in streamly
25−-- allows high performance combinatorial programming even when using byte level
26−-- streams. Streamly API is similar to Haskell lists.
27−--
28−-- == Console Echo Example
29−--
30−-- In the following example, 'repeatM' generates an infinite stream of 'String'
31−-- by repeatedly performing the 'getLine' IO action. 'mapM' then applies
32−-- 'putStrLn' on each element in the stream converting it to stream of '()'.
33−-- Finally, 'drain' folds the stream to IO discarding the () values, thus
34−-- producing only effects.
35−--
36−-- >>> import Data.Function ((&))
37−--
38−-- >>> :{
39−-- echo =
40−-- Stream.repeatM getLine -- Stream IO String
41−-- & Stream.mapM putStrLn -- Stream IO ()
42−-- & Stream.fold Fold.drain -- IO ()
43−-- :}
44−--
45−-- This is a console echo program. It is an example of a declarative loop
46−-- written using streaming combinators. Compare it with an imperative @while@
47−-- loop.
48−--
49−-- Hopefully, this gives you an idea how we can program declaratively by
50−-- representing loops using streams. In this module, you can find all
51−-- "Data.List" like functions and many more powerful combinators to perform
52−-- common programming tasks.
53−--
54−-- == Performance Notes
55−--
56−-- The 'Stream' type represents a stream by composing state as data which
57−-- enables stream fusion. Stream fusion generates a tight loop without any
58−-- constructor allocations between the stages, providing C like performance for
59−-- the loop. Stream fusion works when multiple functions are combined in a
60−-- pipeline statically. Therefore, the operations in this module must be
61−-- inlined and must not be used recursively to allow for stream fusion.
62−--
63−-- Using the 'Stream' type binary stream construction operations like 'cons',
64−-- 'append' etc. degrade quadratically (O(n^2)) when combined many times. If
65−-- you need to combine these operations, say more than 50 times in a single
66−-- loop, then you should use the continuation style stream type 'StreamK'
67−-- instead. Also, if you need to use these operations in a recursive loop you
68−-- should use 'StreamK' instead.
69−--
70−-- The 'StreamK' type represents a stream by composing function calls,
71−-- therefore, a function call overhead is incurred at each composition. It is
72−-- quite fast in general but may be a few times slower than a fused stream.
73−-- However, it allows for scalable dynamic composition and control flow
74−-- manipulation. Using the 'StreamK' type binary operations like 'cons' and
75−-- 'append' provide linear (O(n)) performance.
76−--
77−-- 'Stream' and 'StreamK' types can be interconverted.
78−--
79−-- == Useful Idioms
80−--
81−-- >>> fromListM = Stream.sequence . Stream.fromList
82−-- >>> fromIndices f = fmap f $ Stream.enumerateFrom 0
83−--
84−-- Also see "Streamly.Internal.Data.Stream" module for many more @Pre-release@
85−-- combinators. See the <https://github.com/composewell/streamly-examples>
17+-- Checkout the <https://github.com/composewell/streamly-examples>
86-- repository for many more real world examples of stream programming.
18-- repository for many more real world examples of stream programming.
87−--
19+
88module Streamly.Data.Stream
20module Streamly.Data.Stream
89 (
21 (
22+ -- * Setup
23+ -- | To execute the code examples provided in this module in ghci, please
24+ -- run the following commands first.
25+ --
26+ -- $setup
27+
28+ -- * Overview
29+ -- $overview
30+
31+ -- * The Stream Type
90 Stream
32 Stream
33+
91 -- * Construction
34 -- * Construction
92 -- | Functions ending in the general shape @b -> Stream m a@.
35 -- | Functions ending in the general shape @b -> Stream m a@.
93 --
36 --
@@ -522,3 +465,68 @@ import Prelude
522 notElem, maximum, minimum, head, last, tail, length, null,
465 notElem, maximum, minimum, head, last, tail, length, null,
523 reverse, iterate, init, and, or, lookup, foldr1, (!!),
466 reverse, iterate, init, and, or, lookup, foldr1, (!!),
524 scanl, scanl1, repeat, replicate, concatMap, span)
467 scanl, scanl1, repeat, replicate, concatMap, span)
468+
469+#include "DocTestDataStream.hs"
470+
471+-- $overview
472+--
473+-- Streamly is a framework for modular data flow based programming and
474+-- declarative concurrency. Powerful stream fusion framework in streamly
475+-- allows high performance combinatorial programming even when using byte level
476+-- streams. Streamly API is similar to Haskell lists.
477+--
478+-- == Console Echo Example
479+--
480+-- In the following example, 'repeatM' generates an infinite stream of 'String'
481+-- by repeatedly performing the 'getLine' IO action. 'mapM' then applies
482+-- 'putStrLn' on each element in the stream converting it to stream of '()'.
483+-- Finally, 'drain' folds the stream to IO discarding the () values, thus
484+-- producing only effects.
485+--
486+-- >>> import Data.Function ((&))
487+--
488+-- >>> :{
489+-- echo =
490+-- Stream.repeatM getLine -- Stream IO String
491+-- & Stream.mapM putStrLn -- Stream IO ()
492+-- & Stream.fold Fold.drain -- IO ()
493+-- :}
494+--
495+-- This is a console echo program. It is an example of a declarative loop
496+-- written using streaming combinators. Compare it with an imperative @while@
497+-- loop.
498+--
499+-- Hopefully, this gives you an idea how we can program declaratively by
500+-- representing loops using streams. In this module, you can find all
501+-- "Data.List" like functions and many more powerful combinators to perform
502+-- common programming tasks.
503+--
504+-- == Performance Notes
505+--
506+-- The 'Stream' type represents a stream by composing state as data which
507+-- enables stream fusion. Stream fusion generates a tight loop without any
508+-- constructor allocations between the stages, providing C like performance for
509+-- the loop. Stream fusion works when multiple functions are combined in a
510+-- pipeline statically. Therefore, the operations in this module must be
511+-- inlined and must not be used recursively to allow for stream fusion.
512+--
513+-- Using the 'Stream' type binary stream construction operations like 'cons',
514+-- 'append' etc. degrade quadratically (O(n^2)) when combined many times. If
515+-- you need to combine these operations, say more than 50 times in a single
516+-- loop, then you should use the continuation style stream type 'StreamK'
517+-- instead. Also, if you need to use these operations in a recursive loop you
518+-- should use 'StreamK' instead.
519+--
520+-- The 'StreamK' type represents a stream by composing function calls,
521+-- therefore, a function call overhead is incurred at each composition. It is
522+-- quite fast in general but may be a few times slower than a fused stream.
523+-- However, it allows for scalable dynamic composition and control flow
524+-- manipulation. Using the 'StreamK' type binary operations like 'cons' and
525+-- 'append' provide linear (O(n)) performance.
526+--
527+-- 'Stream' and 'StreamK' types can be interconverted.
528+--
529+-- == Useful Idioms
530+--
531+-- >>> fromListM = Stream.sequence . Stream.fromList
532+-- >>> fromIndices f = fmap f $ Stream.enumerateFrom 0
core/src/Streamly/Internal/Data/Stream/StreamD/Container.hs+2−3
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Container
3-- Module : Streamly.Internal.Data.Stream.StreamD.Container
3-- Copyright : (c) 2019 Composewell Technologies
4-- Copyright : (c) 2019 Composewell Technologies
@@ -44,9 +45,7 @@ import qualified Streamly.Internal.Data.Stream.StreamD.Generate as Stream
44import qualified Streamly.Internal.Data.Stream.StreamD.Transform as Stream
45import qualified Streamly.Internal.Data.Stream.StreamD.Transform as Stream
45import qualified Streamly.Internal.Data.Stream.StreamD.Transformer as Stream
46import qualified Streamly.Internal.Data.Stream.StreamD.Transformer as Stream
46
47
47−-- $setup
48+#include "DocTestDataStream.hs"
48−-- >>> :m
49−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
50
49
51-- | The memory used is proportional to the number of unique elements in the
50-- | The memory used is proportional to the number of unique elements in the
52-- stream. If we want to limit the memory we can just use "take" to limit the
51-- stream. If we want to limit the memory we can just use "take" to limit the
core/src/Streamly/Internal/Data/Stream/StreamD/Eliminate.hs+2−7
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Eliminate
3-- Module : Streamly.Internal.Data.Stream.StreamD.Eliminate
3-- Copyright : (c) 2018 Composewell Technologies
4-- Copyright : (c) 2018 Composewell Technologies
@@ -107,13 +108,7 @@ import Prelude hiding
107 , maximum, minimum, notElem, null, splitAt, tail, (!!))
108 , maximum, minimum, notElem, null, splitAt, tail, (!!))
108import Streamly.Internal.Data.Stream.StreamD.Type
109import Streamly.Internal.Data.Stream.StreamD.Type
109
110
110−-- $setup
111+#include "DocTestDataStream.hs"
111−-- >>> :m
112−-- >>> import Streamly.Internal.Data.Stream (Stream)
113−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
114−-- >>> import qualified Streamly.Internal.Data.Parser as Parser
115−-- >>> import qualified Streamly.Internal.Data.Fold as Fold
116−-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
117
112
118------------------------------------------------------------------------------
113------------------------------------------------------------------------------
119-- Elimination by Folds
114-- Elimination by Folds
core/src/Streamly/Internal/Data/Stream/StreamD/Exception.hs+2−3
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Exception
3-- Module : Streamly.Internal.Data.Stream.StreamD.Exception
3-- Copyright : (c) 2020 Composewell Technologies and Contributors
4-- Copyright : (c) 2020 Composewell Technologies and Contributors
@@ -37,9 +38,7 @@ import qualified Control.Monad.Catch as MC
37
38
38import Streamly.Internal.Data.Stream.StreamD.Type
39import Streamly.Internal.Data.Stream.StreamD.Type
39
40
40−-- $setup
41+#include "DocTestDataStream.hs"
41−-- >>> :m
42−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
43
42
44data GbracketState s1 s2 v
43data GbracketState s1 s2 v
45 = GBracketInit
44 = GBracketInit
core/src/Streamly/Internal/Data/Stream/StreamD/Generate.hs+2−9
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Generate
3-- Module : Streamly.Internal.Data.Stream.StreamD.Generate
3-- Copyright : (c) 2020 Composewell Technologies and Contributors
4-- Copyright : (c) 2020 Composewell Technologies and Contributors
@@ -136,15 +137,7 @@ import Numeric.Natural
136import Prelude hiding (iterate, repeat, replicate, take, takeWhile)
137import Prelude hiding (iterate, repeat, replicate, take, takeWhile)
137import Streamly.Internal.Data.Stream.StreamD.Type
138import Streamly.Internal.Data.Stream.StreamD.Type
138
139
139−-- $setup
140+#include "DocTestDataStream.hs"
140−-- >>> :m
141−-- >>> import Control.Concurrent (threadDelay)
142−-- >>> import Data.Function (fix, (&))
143−-- >>> import Data.Semigroup (cycle1)
144−-- >>> import qualified Streamly.Data.Fold as Fold
145−-- >>> import qualified Streamly.Data.Unfold as Unfold
146−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
147−-- >>> import GHC.Exts (Ptr (Ptr))
148
141
149------------------------------------------------------------------------------
142------------------------------------------------------------------------------
150-- Primitives
143-- Primitives
core/src/Streamly/Internal/Data/Stream/StreamD/Lift.hs+2−4
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Lift
3-- Module : Streamly.Internal.Data.Stream.StreamD.Lift
3-- Copyright : (c) 2018 Composewell Technologies
4-- Copyright : (c) 2018 Composewell Technologies
@@ -28,10 +29,7 @@ import Streamly.Internal.Data.SVar.Type (adaptState)
28
29
29import Streamly.Internal.Data.Stream.StreamD.Type
30import Streamly.Internal.Data.Stream.StreamD.Type
30
31
31−-- $setup
32+#include "DocTestDataStream.hs"
32−-- >>> :m
33−-- >>> import Data.Functor.Identity (runIdentity)
34−-- >>> import Streamly.Internal.Data.Stream as Stream
35
33
36-------------------------------------------------------------------------------
34-------------------------------------------------------------------------------
37-- Generalize Inner Monad
35-- Generalize Inner Monad
core/src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+2−13
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Nesting
3-- Module : Streamly.Internal.Data.Stream.StreamD.Nesting
3-- Copyright : (c) 2018 Composewell Technologies
4-- Copyright : (c) 2018 Composewell Technologies
@@ -201,19 +202,7 @@ import Streamly.Internal.Data.Stream.StreamD.Type
201
202
202import Prelude hiding (concatMap, mapM, zipWith)
203import Prelude hiding (concatMap, mapM, zipWith)
203
204
204−-- $setup
205+#include "DocTestDataStream.hs"
205−-- >>> :m
206−-- >>> import Data.Either (either)
207−-- >>> import Data.IORef
208−-- >>> import Streamly.Internal.Data.Stream (Stream)
209−-- >>> import Prelude hiding (zipWith, concatMap, concat)
210−-- >>> import qualified Streamly.Data.Array as Array
211−-- >>> import qualified Streamly.Internal.Data.Fold as Fold
212−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
213−-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
214−-- >>> import qualified Streamly.Internal.Data.Parser as Parser
215−-- >>> import qualified Streamly.Internal.FileSystem.Dir as Dir
216−--
217
206
218------------------------------------------------------------------------------
207------------------------------------------------------------------------------
219-- Appending
208-- Appending
core/src/Streamly/Internal/Data/Stream/StreamD/Top.hs+2−5
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Top
3-- Module : Streamly.Internal.Data.Stream.StreamD.Top
3-- Copyright : (c) 2020 Composewell Technologies
4-- Copyright : (c) 2020 Composewell Technologies
@@ -58,11 +59,7 @@ import qualified Streamly.Internal.Data.Stream.StreamD.Transform as Stream
58
59
59import Prelude hiding (filter, zipWith, concatMap, concat)
60import Prelude hiding (filter, zipWith, concatMap, concat)
60
61
61−-- $setup
62+#include "DocTestDataStream.hs"
62−-- >>> :m
63−-- >>> import Prelude hiding (filter, zipWith, concatMap, concat)
64−-- >>> import qualified Streamly.Internal.Data.Fold as Fold
65−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
66
63
67------------------------------------------------------------------------------
64------------------------------------------------------------------------------
68-- Sampling
65-- Sampling
core/src/Streamly/Internal/Data/Stream/StreamD/Transform.hs+2−19
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Transform
3-- Module : Streamly.Internal.Data.Stream.StreamD.Transform
3-- Copyright : (c) 2018 Composewell Technologies
4-- Copyright : (c) 2018 Composewell Technologies
@@ -182,25 +183,7 @@ import Streamly.Internal.Data.Stream.StreamD.Generate
182 (absTimesWith, relTimesWith)
183 (absTimesWith, relTimesWith)
183import Streamly.Internal.Data.Stream.StreamD.Type
184import Streamly.Internal.Data.Stream.StreamD.Type
184
185
185−--
186+#include "DocTestDataStream.hs"
186−-- $setup
187−-- >>> :m
188−-- >>> import Control.Concurrent (threadDelay)
189−-- >>> import Control.Monad (void)
190−-- >>> import Control.Monad.IO.Class (MonadIO (liftIO))
191−-- >>> import Data.Either (fromLeft, fromRight, isLeft, isRight, either)
192−-- >>> import Data.Function ((&))
193−-- >>> import Data.Maybe (fromJust, isJust)
194−-- >>> import Prelude hiding (filter, drop, dropWhile, take, takeWhile, foldr, map, mapM, sequence, reverse, foldr1 , scanl, scanl1)
195−-- >>> import Streamly.Internal.Data.Stream (Stream)
196−-- >>> import qualified Streamly.Data.Fold as Fold
197−-- >>> import qualified Streamly.Data.Unfold as Unfold
198−-- >>> import qualified Streamly.Internal.Data.Fold as Fold (filtering)
199−-- >>> import qualified Streamly.Internal.Data.Fold.Window as Window
200−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
201−-- >>> import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
202−--
203−-- >>> hSetBuffering stdout LineBuffering
204
187
205------------------------------------------------------------------------------
188------------------------------------------------------------------------------
206-- Piping
189-- Piping
core/src/Streamly/Internal/Data/Stream/StreamD/Transformer.hs+2−5
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- |
2-- |
2-- Module : Streamly.Internal.Data.Stream.StreamD.Transformer
3-- Module : Streamly.Internal.Data.Stream.StreamD.Transformer
3-- Copyright : (c) 2018 Composewell Technologies
4-- Copyright : (c) 2018 Composewell Technologies
@@ -36,11 +37,7 @@ import qualified Control.Monad.Trans.State.Strict as State
36
37
37import Streamly.Internal.Data.Stream.StreamD.Type
38import Streamly.Internal.Data.Stream.StreamD.Type
38
39
39−-- $setup
40+#include "DocTestDataStream.hs"
40−-- >>> :m
41−-- >>> import Control.Monad.Trans.Class (lift)
42−-- >>> import Control.Monad.Trans.Identity (runIdentityT)
43−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
44
41
45-- | Lazy left fold to a transformer monad.
42-- | Lazy left fold to a transformer monad.
46--
43--
core/src/Streamly/Internal/Data/Stream/StreamD/Type.hs+5−12
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1{-# LANGUAGE UndecidableInstances #-}
2{-# LANGUAGE UndecidableInstances #-}
2
3
3-- |
4-- |
@@ -167,15 +168,7 @@ import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
167import qualified Streamly.Internal.Data.Unfold.Type as Unfold
168import qualified Streamly.Internal.Data.Unfold.Type as Unfold
168#endif
169#endif
169
170
170−-- $setup
171+#include "DocTestDataStream.hs"
171−-- >>> import Streamly.Internal.Data.Stream (CrossStream(..))
172−-- >>> import qualified Streamly.Data.Fold as Fold
173−-- >>> import qualified Streamly.Data.Parser as Parser
174−-- >>> import qualified Streamly.Data.Stream as Stream
175−-- >>> import qualified Streamly.Data.Unfold as Unfold
176−-- >>> import qualified Streamly.Internal.Data.Stream as Stream
177−-- >>> import qualified Streamly.Internal.FileSystem.Dir as Dir
178−-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
179
172
180------------------------------------------------------------------------------
173------------------------------------------------------------------------------
181-- The direct style stream type
174-- The direct style stream type
@@ -308,7 +301,7 @@ unfold (Unfold ustep inject) seed = Stream step UnfoldNothing
308--
301--
309-- >>> fromPure a = a `Stream.cons` Stream.nil
302-- >>> fromPure a = a `Stream.cons` Stream.nil
310-- >>> fromPure = pure
303-- >>> fromPure = pure
311−-- >>> fromPure = fromEffect . pure
304+-- >>> fromPure = Stream.fromEffect . pure
312--
305--
313{-# INLINE_NORMAL fromPure #-}
306{-# INLINE_NORMAL fromPure #-}
314fromPure :: Applicative m => a -> Stream m a
307fromPure :: Applicative m => a -> Stream m a
@@ -320,7 +313,7 @@ fromPure x = Stream (\_ s -> pure $ step undefined s) True
320
313
321-- | Create a singleton stream from a monadic action.
314-- | Create a singleton stream from a monadic action.
322--
315--
323−-- >>> fromEffect m = m `consM` Stream.nil
316+-- >>> fromEffect m = m `Stream.consM` Stream.nil
324-- >>> fromEffect = Stream.sequence . Stream.fromPure
317-- >>> fromEffect = Stream.sequence . Stream.fromPure
325--
318--
326-- >>> Stream.fold Fold.drain $ Stream.fromEffect (putStrLn "hello")
319-- >>> Stream.fold Fold.drain $ Stream.fromEffect (putStrLn "hello")
@@ -1383,7 +1376,7 @@ concat = concatMap id
1383-- monad with the stream monad.
1376-- monad with the stream monad.
1384--
1377--
1385-- >>> concatEffect = Stream.concat . Stream.fromEffect
1378-- >>> concatEffect = Stream.concat . Stream.fromEffect
1386−-- >>> concatEffect eff = Stream.concatMapM (\() -> eff) (fromPure ())
1379+-- >>> concatEffect eff = Stream.concatMapM (\() -> eff) (Stream.fromPure ())
1387--
1380--
1388-- See also: 'concat', 'sequence'
1381-- See also: 'concat', 'sequence'
1389--
1382--
core/streamly-core.cabal+1
@@ -43,6 +43,7 @@ extra-source-files:
43 src/DocTestDataMutArray.hs
43 src/DocTestDataMutArray.hs
44 src/DocTestDataMutArrayGeneric.hs
44 src/DocTestDataMutArrayGeneric.hs
45 src/DocTestDataParser.hs
45 src/DocTestDataParser.hs
46+ src/DocTestDataStream.hs
46
47
47 -- This is duplicated
48 -- This is duplicated
48 src/Streamly/Internal/Data/Array/ArrayMacros.h
49 src/Streamly/Internal/Data/Array/ArrayMacros.h