on master help sign in
Fix doctests in Streamly.Prelude
9c88791Harendra Kumar
src/Streamly/Internal/Data/Stream/Ahead.hs+23−3
@@ -9,6 +9,16 @@
9-- Stability : experimental
9-- Stability : experimental
10-- Portability : GHC
10-- Portability : GHC
11--
11--
12+-- To run examples in this module:
13+--
14+-- >>> import qualified Streamly.Prelude as Stream
15+-- >>> import Control.Concurrent (threadDelay)
16+-- >>> :{
17+-- delay n = do
18+-- threadDelay (n * 1000000) -- sleep for n seconds
19+-- putStrLn (show n ++ " sec") -- print "n sec"
20+-- return n -- IO Int
21+-- :}
12--
22--
13module Streamly.Internal.Data.Stream.Ahead
23module Streamly.Internal.Data.Stream.Ahead
14 (
24 (
@@ -53,6 +63,15 @@ import Prelude hiding (map)
53
63
54#include "Instances.hs"
64#include "Instances.hs"
55
65
66+-- $setup
67+-- >>> import Control.Concurrent (threadDelay)
68+-- >>> :{
69+-- delay n = do
70+-- threadDelay (n * 1000000) -- sleep for n seconds
71+-- putStrLn (show n ++ " sec") -- print "n sec"
72+-- return n -- IO Int
73+-- :}
74+
56-------------------------------------------------------------------------------
75-------------------------------------------------------------------------------
57-- Ahead
76-- Ahead
58-------------------------------------------------------------------------------
77-------------------------------------------------------------------------------
@@ -600,9 +619,10 @@ infixr 6 `ahead`
600-- original streams, side effects will happen in the order in which the streams
619-- original streams, side effects will happen in the order in which the streams
601-- are evaluated:
620-- are evaluated:
602--
621--
622+-- >>> import Streamly.Prelude (ahead)
603−-- >>> stream1 = Stream.yieldM (delay 4) -- SerialT IO Int
623+-- >>> stream1 = Stream.yieldM (delay 4) :: SerialT IO Int
604−-- >>> stream2 = Stream.yieldM (delay 2) -- SerialT IO Int
624+-- >>> stream2 = Stream.yieldM (delay 2) :: SerialT IO Int
605−-- >>> Stream.toList $ stream1 `ahead` stream2 -- IO [Int]
625+-- >>> Stream.toList $ stream1 `ahead` stream2 :: IO [Int]
606-- 2 sec
626-- 2 sec
607-- 4 sec
627-- 4 sec
608-- [4,2]
628-- [4,2]
src/Streamly/Internal/Data/Stream/Async.hs+32−4
@@ -11,6 +11,16 @@
11-- Stability : experimental
11-- Stability : experimental
12-- Portability : GHC
12-- Portability : GHC
13--
13--
14+-- To run examples in this module:
15+--
16+-- >>> import qualified Streamly.Prelude as Stream
17+-- >>> import Control.Concurrent (threadDelay)
18+-- >>> :{
19+-- delay n = do
20+-- threadDelay (n * 1000000) -- sleep for n seconds
21+-- putStrLn (show n ++ " sec") -- print "n sec"
22+-- return n -- IO Int
23+-- :}
14--
24--
15module Streamly.Internal.Data.Stream.Async
25module Streamly.Internal.Data.Stream.Async
16 (
26 (
@@ -61,6 +71,15 @@ import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
61
71
62#include "Instances.hs"
72#include "Instances.hs"
63
73
74+-- $setup
75+-- >>> import Control.Concurrent (threadDelay)
76+-- >>> :{
77+-- delay n = do
78+-- threadDelay (n * 1000000) -- sleep for n seconds
79+-- putStrLn (show n ++ " sec") -- print "n sec"
80+-- return n -- IO Int
81+-- :}
82+
64-------------------------------------------------------------------------------
83-------------------------------------------------------------------------------
65-- Async
84-- Async
66-------------------------------------------------------------------------------
85-------------------------------------------------------------------------------
@@ -637,27 +656,33 @@ infixr 6 `async`
637-- | Merges two streams, both the streams may be evaluated concurrently,
656-- | Merges two streams, both the streams may be evaluated concurrently,
638-- outputs from both are used as they arrive:
657-- outputs from both are used as they arrive:
639--
658--
659+-- >>> import Streamly.Prelude (async)
640-- >>> stream1 = Stream.yieldM (delay 4)
660-- >>> stream1 = Stream.yieldM (delay 4)
641-- >>> stream2 = Stream.yieldM (delay 2)
661-- >>> stream2 = Stream.yieldM (delay 2)
642-- >>> Stream.toList $ stream1 `async` stream2
662-- >>> Stream.toList $ stream1 `async` stream2
643−-- [4,2]
663+-- 2 sec
664+-- 4 sec
665+-- [2,4]
644--
666--
645-- Multiple streams can be combined. With enough threads, all of them can be
667-- Multiple streams can be combined. With enough threads, all of them can be
646-- scheduled simultaneously:
668-- scheduled simultaneously:
647--
669--
648-- >>> stream3 = Stream.yieldM (delay 1)
670-- >>> stream3 = Stream.yieldM (delay 1)
649-- >>> Stream.toList $ stream1 `async` stream2 `async` stream3
671-- >>> Stream.toList $ stream1 `async` stream2 `async` stream3
672+-- ...
650-- [1,2,4]
673-- [1,2,4]
651--
674--
652-- With 2 threads, only two can be scheduled at a time, when one of those
675-- With 2 threads, only two can be scheduled at a time, when one of those
653-- finishes, the third one gets scheduled:
676-- finishes, the third one gets scheduled:
654--
677--
655-- >>> Stream.toList $ Stream.maxThreads 2 $ stream1 `async` stream2 `async` stream3
678-- >>> Stream.toList $ Stream.maxThreads 2 $ stream1 `async` stream2 `async` stream3
679+-- ...
656-- [2,1,4]
680-- [2,1,4]
657--
681--
658-- With a single thread, it becomes serial:
682-- With a single thread, it becomes serial:
659--
683--
660-- >>> Stream.toList $ Stream.maxThreads 1 $ stream1 `async` stream2 `async` stream3
684-- >>> Stream.toList $ Stream.maxThreads 1 $ stream1 `async` stream2 `async` stream3
685+-- ...
661-- [4,2,1]
686-- [4,2,1]
662--
687--
663-- Only streams are scheduled for async evaluation, how actions within a
688-- Only streams are scheduled for async evaluation, how actions within a
@@ -667,16 +692,18 @@ infixr 6 `async`
667-- In the following example, both the streams are scheduled for concurrent
692-- In the following example, both the streams are scheduled for concurrent
668-- evaluation but each individual stream is evaluated serially:
693-- evaluation but each individual stream is evaluated serially:
669--
694--
670−-- >>> stream1 = Stream.fromListM $ map delay [3,3] -- SerialT IO Int
695+-- >>> stream1 = Stream.fromListM $ Prelude.map delay [3,3] -- SerialT IO Int
671−-- >>> stream2 = Stream.fromListM $ map delay [1,1] -- SerialT IO Int
696+-- >>> stream2 = Stream.fromListM $ Prelude.map delay [1,1] -- SerialT IO Int
672-- >>> Stream.toList $ stream1 `async` stream2 -- IO [Int]
697-- >>> Stream.toList $ stream1 `async` stream2 -- IO [Int]
698+-- ...
673-- [1,1,3,3]
699-- [1,1,3,3]
674--
700--
675-- If total threads are 2, the third stream is scheduled only after one of the
701-- If total threads are 2, the third stream is scheduled only after one of the
676-- first two has finished:
702-- first two has finished:
677--
703--
678−-- >>> stream3 = Stream.fromListM $ map delay [2,2] -- SerialT IO Int
704+-- >>> stream3 = Stream.fromListM $ Prelude.map delay [2,2] -- SerialT IO Int
679-- >>> Stream.toList $ Stream.maxThreads 2 $ stream1 `async` stream2 `async` stream3 -- IO [Int]
705-- >>> Stream.toList $ Stream.maxThreads 2 $ stream1 `async` stream2 `async` stream3 -- IO [Int]
706+-- ...
680-- [1,1,3,2,3,2]
707-- [1,1,3,2,3,2]
681--
708--
682-- Thus 'async' goes deep in first few streams rather than going wide in all
709-- Thus 'async' goes deep in first few streams rather than going wide in all
@@ -867,6 +894,7 @@ infixr 6 `wAsync`
867-- With a single thread, 'async' starts behaving like 'serial' while 'wAsync'
894-- With a single thread, 'async' starts behaving like 'serial' while 'wAsync'
868-- starts behaving like 'wSerial'.
895-- starts behaving like 'wSerial'.
869--
896--
897+-- >>> import Streamly.Prelude (wAsync)
870-- >>> stream1 = Stream.fromList [1,2,3]
898-- >>> stream1 = Stream.fromList [1,2,3]
871-- >>> stream2 = Stream.fromList [4,5,6]
899-- >>> stream2 = Stream.fromList [4,5,6]
872-- >>> Stream.toList $ Stream.asyncly $ Stream.maxThreads 1 $ stream1 `async` stream2
900-- >>> Stream.toList $ Stream.asyncly $ Stream.maxThreads 1 $ stream1 `async` stream2
src/Streamly/Internal/Data/Stream/Parallel.hs+18−4
@@ -11,6 +11,16 @@
11-- Stability : experimental
11-- Stability : experimental
12-- Portability : GHC
12-- Portability : GHC
13--
13--
14+-- To run examples in this module:
15+--
16+-- >>> import qualified Streamly.Prelude as Stream
17+-- >>> import Control.Concurrent (threadDelay)
18+-- >>> :{
19+-- delay n = do
20+-- threadDelay (n * 1000000) -- sleep for n seconds
21+-- putStrLn (show n ++ " sec") -- print "n sec"
22+-- return n -- IO Int
23+-- :}
14--
24--
15module Streamly.Internal.Data.Stream.Parallel
25module Streamly.Internal.Data.Stream.Parallel
16 (
26 (
@@ -74,10 +84,13 @@ import qualified Streamly.Internal.Data.Stream.SVar as SVar
74
84
75--
85--
76-- $setup
86-- $setup
77−-- >>> :m
87+-- >>> import Control.Concurrent (threadDelay)
78−-- >>> import Prelude hiding (map)
88+-- >>> :{
79−-- >>> import qualified Streamly.Prelude as Stream
89+-- delay n = do
80−-- >>> import Streamly.Internal.Data.Stream.IsStream as Stream
90+-- threadDelay (n * 1000000) -- sleep for n seconds
91+-- putStrLn (show n ++ " sec") -- print "n sec"
92+-- return n -- IO Int
93+-- :}
81
94
82-------------------------------------------------------------------------------
95-------------------------------------------------------------------------------
83-- Parallel
96-- Parallel
@@ -229,6 +242,7 @@ infixr 6 `parallel`
229-- The only limit that applies to 'parallel' is 'Streamly.Prelude.maxBuffer'.
242-- The only limit that applies to 'parallel' is 'Streamly.Prelude.maxBuffer'.
230-- Evaluation may block if the output buffer becomes full.
243-- Evaluation may block if the output buffer becomes full.
231--
244--
245+-- >>> import Streamly.Prelude (parallel)
232-- >>> stream = Stream.yieldM (delay 2) `parallel` Stream.yieldM (delay 1)
246-- >>> stream = Stream.yieldM (delay 2) `parallel` Stream.yieldM (delay 1)
233-- >>> Stream.toList stream -- IO [Int]
247-- >>> Stream.toList stream -- IO [Int]
234-- 1 sec
248-- 1 sec
src/Streamly/Internal/Data/Stream/Serial.hs+2−1
@@ -281,7 +281,7 @@ TRAVERSABLE_INSTANCE(SerialT)
281-- element @1@ in the first stream with all the nested iterations of element
281-- element @1@ in the first stream with all the nested iterations of element
282-- @2@:
282-- @2@:
283--
283--
284−-- >>> Stream.fromList [(1,3),(1,4)] `wSerial` Stream.fromList [(2,3),(2,4)]
284+-- >>> Stream.toList $ Stream.fromList [(1,3),(1,4)] `wSerial` Stream.fromList [(2,3),(2,4)]
285-- [(1,3),(2,3),(1,4),(2,4)]
285-- [(1,3),(2,3),(1,4),(2,4)]
286--
286--
287-- The @W@ in the name stands for @wide@ or breadth wise scheduling in
287-- The @W@ in the name stands for @wide@ or breadth wise scheduling in
@@ -355,6 +355,7 @@ infixr 6 `wSerial`
355-- alternately. When one stream stops the rest of the other stream is used in
355-- alternately. When one stream stops the rest of the other stream is used in
356-- the output stream.
356-- the output stream.
357--
357--
358+-- >>> import Streamly.Prelude (wSerial)
358-- >>> stream1 = Stream.fromList [1,2]
359-- >>> stream1 = Stream.fromList [1,2]
359-- >>> stream2 = Stream.fromList [3,4]
360-- >>> stream2 = Stream.fromList [3,4]
360-- >>> Stream.toList $ Stream.wSerially $ stream1 `wSerial` stream2
361-- >>> Stream.toList $ Stream.wSerially $ stream1 `wSerial` stream2
src/Streamly/Internal/Data/Stream/StreamK/Type.hs+1
@@ -809,6 +809,7 @@ infixr 6 `serial`
809-- | Appends two streams sequentially, yielding all elements from the first
809-- | Appends two streams sequentially, yielding all elements from the first
810-- stream, and then all elements from the second stream.
810-- stream, and then all elements from the second stream.
811--
811--
812+-- >>> import Streamly.Prelude (serial)
812-- >>> stream1 = Stream.fromList [1,2]
813-- >>> stream1 = Stream.fromList [1,2]
813-- >>> stream2 = Stream.fromList [3,4]
814-- >>> stream2 = Stream.fromList [3,4]
814-- >>> Stream.toList $ stream1 `serial` stream2
815-- >>> Stream.toList $ stream1 `serial` stream2
src/Streamly/Internal/Data/Stream/Zip.hs+7−8
@@ -9,6 +9,9 @@
9-- Stability : experimental
9-- Stability : experimental
10-- Portability : GHC
10-- Portability : GHC
11--
11--
12+-- To run examples in this module:
13+--
14+-- >>> import qualified Streamly.Prelude as Stream
12--
15--
13module Streamly.Internal.Data.Stream.Zip
16module Streamly.Internal.Data.Stream.Zip
14 (
17 (
@@ -121,15 +124,11 @@ zipAsyncWith f = zipAsyncWithM (\a b -> return (f a b))
121-- i.e. it produces one element from each stream serially and then zips all
124-- i.e. it produces one element from each stream serially and then zips all
122-- those elements.
125-- those elements.
123--
126--
124−-- @
125−-- main = (toList . 'zipSerially' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
126−-- where s1 = fromFoldable [1, 2]
127+-- >>> s1 = Stream.fromFoldable [1, 2]
127−-- s2 = fromFoldable [3, 4]
128+-- >>> s2 = Stream.fromFoldable [3, 4]
128−-- s3 = fromFoldable [5, 6]
129+-- >>> s3 = Stream.fromFoldable [5, 6]
129−-- @
130+-- >>> Stream.toList $ Stream.zipSerially $ (,,) <$> s1 <*> s2 <*> s3
130−-- @
131-- [(1,3,5),(2,4,6)]
131-- [(1,3,5),(2,4,6)]
132−-- @
133--
132--
134-- The 'Semigroup' instance of this type works the same way as that of
133-- The 'Semigroup' instance of this type works the same way as that of
135-- 'SerialT'.
134-- 'SerialT'.
src/Streamly/Prelude.hs+12−14
@@ -29,7 +29,7 @@
29-- which is more or less the same as a list:
29-- which is more or less the same as a list:
30--
30--
31-- >>> import Streamly.Prelude (SerialT, cons, consM, nil)
31-- >>> import Streamly.Prelude (SerialT, cons, consM, nil)
32−-- >>> stream :: SerialT IO Int = 1 `cons` 2 `cons` nil
32+-- >>> stream = 1 `cons` 2 `cons` nil :: SerialT IO Int
33-- >>> Stream.toList stream -- IO [Int]
33-- >>> Stream.toList stream -- IO [Int]
34-- [1,2]
34-- [1,2]
35--
35--
@@ -43,8 +43,10 @@
43-- putStrLn (show n ++ " sec") -- print "n sec"
43-- putStrLn (show n ++ " sec") -- print "n sec"
44-- return n -- IO Int
44-- return n -- IO Int
45-- :}
45-- :}
46+--
46-- >>> delay 1
47-- >>> delay 1
47-- 1 sec
48-- 1 sec
49+-- 1
48--
50--
49-- 'consM' constructs a stream from effectful actions:
51-- 'consM' constructs a stream from effectful actions:
50--
52--
@@ -62,11 +64,15 @@
62-- Finally, 'drain' folds the stream to IO discarding the () values, thus
64-- Finally, 'drain' folds the stream to IO discarding the () values, thus
63-- producing only effects.
65-- producing only effects.
64--
66--
65−-- >>> :{
67+-- >>> import Data.Function ((&))
68+--
69+-- @
70+-- :{
66-- Stream.repeatM getLine -- SerialT IO String
71-- Stream.repeatM getLine -- SerialT IO String
67-- & Stream.mapM putStrLn -- SerialT IO ()
72-- & Stream.mapM putStrLn -- SerialT IO ()
68-- & Stream.drain -- IO ()
73-- & Stream.drain -- IO ()
69-- :}
74-- :}
75+-- @
70--
76--
71-- This is a console echo program. It is an example of a declarative loop.
77-- This is a console echo program. It is an example of a declarative loop.
72-- Compare it with an imperative @while@ loop.
78-- Compare it with an imperative @while@ loop.
@@ -84,7 +90,7 @@
84-- 'SerialT' executes actions serially, so the total delay in the following
90-- 'SerialT' executes actions serially, so the total delay in the following
85-- example is @2 + 1 = 3@ seconds:
91-- example is @2 + 1 = 3@ seconds:
86--
92--
87−-- >>> stream :: SerialT IO Int = delay 2 `consM` delay 1 `consM` nil
93+-- >>> stream = delay 2 `consM` delay 1 `consM` nil
88-- >>> Stream.toList stream -- IO [Int]
94-- >>> Stream.toList stream -- IO [Int]
89-- 2 sec
95-- 2 sec
90-- 1 sec
96-- 1 sec
@@ -93,8 +99,7 @@
93-- 'AsyncT' executes the actions concurrently, so the total delay is @max 2 1 =
99-- 'AsyncT' executes the actions concurrently, so the total delay is @max 2 1 =
94-- 2@ seconds:
100-- 2@ seconds:
95--
101--
96−-- >>> stream :: AsyncT IO Int = delay 2 `consM` delay 1 `consM` nil
97−-- >>> Stream.toList stream -- IO [Int]
102+-- >>> Stream.toList $ Stream.asyncly stream -- IO [Int]
98-- 1 sec
103-- 1 sec
99-- 2 sec
104-- 2 sec
100-- [1,2]
105-- [1,2]
@@ -106,8 +111,7 @@
106-- 'AheadT' is similar to 'AsyncT' but the order of results is the same as the
111-- 'AheadT' is similar to 'AsyncT' but the order of results is the same as the
107-- order of actions, even though they execute concurrently:
112-- order of actions, even though they execute concurrently:
108--
113--
109−-- >>> stream :: AheadT IO Int = delay 2 `consM` delay 1 `consM` nil
110−-- >>> Stream.toList stream -- IO [Int]
114+-- >>> Stream.toList $ Stream.aheadly stream -- IO [Int]
111-- 1 sec
115-- 1 sec
112-- 2 sec
116-- 2 sec
113-- [2,1]
117-- [2,1]
@@ -187,8 +191,6 @@
187-- action from the first stream and then one action from the second stream and
191-- action from the first stream and then one action from the second stream and
188-- so on:
192-- so on:
189--
193--
190−-- >>> stream1 = Stream.fromListM [delay 1, delay 2]
191−-- >>> stream2 = Stream.fromListM [delay 3, delay 4]
192-- >>> Stream.toList $ Stream.wSerially $ stream1 <> stream2
194-- >>> Stream.toList $ Stream.wSerially $ stream1 <> stream2
193-- 1 sec
195-- 1 sec
194-- 3 sec
196-- 3 sec
@@ -211,11 +213,7 @@
211-- >>> stream1 = Stream.fromListM [delay 3, delay 4]
213-- >>> stream1 = Stream.fromListM [delay 3, delay 4]
212-- >>> stream2 = Stream.fromListM [delay 1, delay 2]
214-- >>> stream2 = Stream.fromListM [delay 1, delay 2]
213-- >>> Stream.toList $ stream1 `parallel` stream2
215-- >>> Stream.toList $ stream1 `parallel` stream2
214−-- 1 sec
216+-- ...
215−-- 2 sec
216−-- 3 sec
217−-- 4 sec
218−-- [1,2,3,4]
219--
217--
220-- We can use @concatMapWith parallel@ to read concurrently from all incoming
218-- We can use @concatMapWith parallel@ to read concurrently from all incoming
221-- network connections and combine the input streams into a single output
219-- network connections and combine the input streams into a single output