on master help sign in
Fix Tutorial doctest
cbb57f2Ranjeet Kumar Ranjan
src/Streamly/Tutorial.hs+351−336
@@ -178,6 +178,31 @@ import Control.Monad
178import Control.Monad.IO.Class (MonadIO(..))
178import Control.Monad.IO.Class (MonadIO(..))
179import Control.Monad.Trans.Class (MonadTrans (lift))
179import Control.Monad.Trans.Class (MonadTrans (lift))
180
180
181+-- $setup
182+-- >>> :m
183+-- >>> import Prelude hiding (break, map, span, splitAt)
184+-- >>> import qualified Streamly.Prelude as Stream
185+-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse, foldMany)
186+-- >>> import qualified Streamly.Data.Fold as Fold
187+-- >>> import qualified Streamly.Internal.Data.Fold as Fold
188+-- >>> import qualified Streamly.Internal.Data.Parser as Parser
189+-- >>> import Control.Monad.IO.Class (MonadIO(..))
190+-- >>> import Control.Monad.Trans.Class (MonadTrans(lift))
191+-- >>> import Data.Function ((&))
192+-- >>> import Data.Char (toUpper)
193+-- >>> import Control.Concurrent
194+-- >>> import Control.Monad (forever)
195+-- >>> import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
196+-- >>> import Streamly.Prelude
197+--
198+-- >>> :{
199+-- delay n = Stream.fromEffect $ do
200+-- threadDelay (n * 1000000)
201+-- tid <- myThreadId
202+-- putStrLn (show tid ++ ": Delay " ++ show n)
203+-- :}
204+--
205+--
181-- $streams
206-- $streams
182--
207--
183-- The monadic stream API offered by Streamly is very close to the Haskell
208-- The monadic stream API offered by Streamly is very close to the Haskell
@@ -332,35 +357,29 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
332-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
357-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
333--
358--
334-- @
359-- @
335−-- > S.'drain' $ liftIO $ putStrLn "Hello world!"
360+-- >>> Stream.drain $ liftIO $ putStrLn "Hello world!"
336-- Hello world!
361-- Hello world!
362+--
337−-- > S.'drain' $ lift $ putStrLn "Hello world!"
363+-- >>> Stream.drain $ lift $ putStrLn "Hello world!"
338-- Hello world!
364-- Hello world!
365+--
339-- @
366-- @
340--
367--
341
368
342-- $generating
369-- $generating
343--
370--
344−-- We will assume the following imports in this tutorial. Go ahead, fire up a
345−-- GHCi session and import these lines to start playing.
346−--
347−-- @
348−-- > import "Streamly.Prelude" ((|:), (|&))
349−-- > import qualified "Streamly.Prelude" as S
350−--
351−-- > import Control.Concurrent
352−-- @
353−--
354-- 'nil' represents an empty stream and 'consM' or its operator form '|:' adds
371-- 'nil' represents an empty stream and 'consM' or its operator form '|:' adds
355-- a monadic action at the head of the stream.
372-- a monadic action at the head of the stream.
356--
373--
357-- @
374-- @
358−-- > S.'toList' S.'nil'
375+-- >>> Stream.toList Stream.nil
359-- []
376-- []
377+--
360−-- > S.'toList' $ 'getLine' |: 'getLine' |: S.'nil'
378+-- Stream.toList $ getLine |: getLine |: Stream.nil
361-- hello
379-- hello
362-- world
380-- world
363-- ["hello","world"]
381-- ["hello","world"]
382+--
364-- @
383-- @
365--
384--
366-- To create a singleton stream from a pure value use 'fromPure' or 'pure' and to
385-- To create a singleton stream from a pure value use 'fromPure' or 'pure' and to
@@ -369,31 +388,37 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
369-- infinite stream.
388-- infinite stream.
370--
389--
371-- @
390-- @
372−-- > S.'toList' $ 'pure' 1
391+-- >>> Stream.toList $ pure 1
373-- [1]
392-- [1]
393+--
374−-- > S.'toList' $ S.'fromPure' 1
394+-- >>> Stream.toList $ Stream.fromPure 1
375-- [1]
395-- [1]
396+--
376−-- > S.'toList' $ S.'fromEffect' 'getLine'
397+-- Stream.toList $ Stream.fromEffect getLine
377-- hello
398-- hello
378-- ["hello"]
399-- ["hello"]
400+--
379-- @
401-- @
380--
402--
381-- To create a stream from pure values in a 'Foldable' container use
403-- To create a stream from pure values in a 'Foldable' container use
382-- 'fromFoldable' which is equivalent to a fold using 'cons' and 'nil':
404-- 'fromFoldable' which is equivalent to a fold using 'cons' and 'nil':
383--
405--
384-- @
406-- @
385−-- > S.'toList' $ S.'fromFoldable' [1..3]
407+-- >>> Stream.toList $ Stream.fromFoldable [1..3]
386-- [1,2,3]
408-- [1,2,3]
409+--
387−-- > S.'toList' $ 'Prelude.foldr' S.'cons' S.'nil' [1..3]
410+-- >>> Stream.toList $ Prelude.foldr Stream.cons Stream.nil [1..3]
388-- [1,2,3]
411-- [1,2,3]
412+--
389-- @
413-- @
390--
414--
391-- To create a stream from monadic actions in a 'Foldable' container just use a
415-- To create a stream from monadic actions in a 'Foldable' container just use a
392-- right fold using 'consM' and 'nil':
416-- right fold using 'consM' and 'nil':
393--
417--
394-- @
418-- @
395−-- > S.'drain' $ 'Prelude.foldr' ('|:') S.'nil' ['putStr' "Hello ", 'putStrLn' "world!"]
419+-- >>> Stream.drain $ Prelude.foldr (|:) Stream.nil [putStr "Hello ", putStrLn "world!"]
396-- Hello world!
420-- Hello world!
421+--
397-- @
422-- @
398--
423--
399-- For more ways to construct a stream see the module "Streamly.Prelude".
424-- For more ways to construct a stream see the module "Streamly.Prelude".
@@ -410,26 +435,27 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
410-- The following code finishes in 3 seconds (6 seconds when serial):
435-- The following code finishes in 3 seconds (6 seconds when serial):
411--
436--
412-- @
437-- @
413−-- > let p n = threadDelay (n * 1000000) >> return n
438+-- >>> let p n = threadDelay (n * 1000000) >> return n
414−-- > :set +s
415−-- > S.'toList' $ S.'fromParallel' $ p 3 |: p 2 |: p 1 |: S.'nil'
439+-- >>> Stream.toList $ Stream.fromParallel $ p 3 |: p 2 |: p 1 |: Stream.nil
416-- [1,2,3]
440-- [1,2,3]
441+--
417-- (3.01 secs, 2,018,432 bytes)
442-- (3.01 secs, 2,018,432 bytes)
418−-- > S.'toList' $ S.'fromAhead' $ p 3 |: p 2 |: p 1 |: S.'nil'
443+-- >>> Stream.toList $ Stream.fromAhead $ p 3 |: p 2 |: p 1 |: Stream.nil
419-- [3,2,1]
444-- [3,2,1]
445+--
420-- (3.01 secs, 2,055,880 bytes)
446-- (3.01 secs, 2,055,880 bytes)
421-- @
447-- @
422-- The following finishes in 10 seconds (100 seconds when serial):
448-- The following finishes in 10 seconds (100 seconds when serial):
423--
449--
424-- @
450-- @
425−-- > S.'drain' $ S.'fromAsync' $ S.'replicateM' 10 $ p 10
451+-- Stream.'drain' $ Stream.'fromAsync' $ Stream.'replicateM' 10 $ p 10
426-- (10.01 secs, 2,080,320 bytes)
452-- (10.01 secs, 2,080,320 bytes)
427-- @
453-- @
428--
454--
429
455
430-- $eliminating
456-- $eliminating
431--
457--
432−-- We have already seen 'drain' and 'toList' to eliminate a stream in the
458+-- We have already seen 'drain' and toList to eliminate a stream in the
433-- examples above. 'drain' runs a stream discarding the results i.e. only
459-- examples above. 'drain' runs a stream discarding the results i.e. only
434-- for effects. 'toList' runs the stream and collects the results in a list.
460-- for effects. 'toList' runs the stream and collects the results in a list.
435--
461--
@@ -450,8 +476,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
450-- forever:
476-- forever:
451--
477--
452-- @
478-- @
453−-- > import Data.Function ((&))
454−-- > S.'drain' $ S.'repeatM' getLine & S.'mapM' putStrLn
479+-- Stream.'drain' $ Stream.'repeatM' getLine & Stream.'mapM' putStrLn
455-- @
480-- @
456--
481--
457-- The following code snippet reads lines from standard input, filters blank
482-- The following code snippet reads lines from standard input, filters blank
@@ -459,18 +484,14 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
459-- numbers them and prints them:
484-- numbers them and prints them:
460--
485--
461-- @
486-- @
462−-- import qualified "Streamly.Prelude" as S
463−-- import Data.Char (toUpper)
464−-- import Data.Function ((&))
465−--
466−-- main = S.'drain' $
487+-- main = Stream.'drain' $
467−-- S.'repeatM' getLine
488+-- Stream.'repeatM' getLine
468−-- & S.'filter' (not . null)
489+-- & Stream.'filter' (not . null)
469−-- & S.'drop' 1
490+-- & Stream.'drop' 1
470−-- & S.'take' 2
491+-- & Stream.'take' 2
471-- & fmap (map toUpper)
492-- & fmap (map toUpper)
472−-- & S.'zipWith' (\\n s -> show n ++ " " ++ s) (S.'fromFoldable' [1..])
493+-- & Stream.'zipWith' (\\n s -> show n ++ " " ++ s) (Stream.'fromFoldable' [1..])
473−-- & S.'mapM' putStrLn
494+-- & Stream.'mapM' putStrLn
474-- @
495-- @
475
496
476-- $concurrentTransformation
497-- $concurrentTransformation
@@ -483,8 +504,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
483-- This would print a value every second (2 seconds when serial):
504-- This would print a value every second (2 seconds when serial):
484--
505--
485-- @
506-- @
486−-- > let p n = threadDelay (n * 1000000) >> return n
507+-- let p n = threadDelay (n * 1000000) >> return n
487−-- > S.'drain' $ S.'fromAhead' $ S.'mapM' (\\x -> p 1 >> print x) (S.'fromSerial' $ S.'repeatM' (p 1))
508+-- Stream.'drain' $ Stream.'fromAhead' $ Stream.'mapM' (\\x -> p 1 >> print x) (Stream.'fromSerial' $ Stream.'repeatM' (p 1))
488-- @
509-- @
489--
510--
490
511
@@ -498,8 +519,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
498-- second instead of 2 seconds in the following:
519-- second instead of 2 seconds in the following:
499--
520--
500-- @
521-- @
501−-- > let p n = threadDelay (n * 1000000) >> return n
522+-- let p n = threadDelay (n * 1000000) >> return n
502−-- > S.'drain' $ S.'repeatM' (p 1) '|&' S.'mapM' (\\x -> p 1 >> print x)
523+-- Stream.'drain' $ Stream.'repeatM' (p 1) '|&' Stream.'mapM' (\\x -> p 1 >> print x)
503-- @
524-- @
504
525
505-- $semigroup
526-- $semigroup
@@ -517,11 +538,20 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
517-- not explicitly specified use the imports shown below.
538-- not explicitly specified use the imports shown below.
518--
539--
519-- @
540-- @
520−-- import "Streamly.Prelude" ((|:), nil)
521−-- import qualified "Streamly.Prelude" as S
522−--
523−-- import Control.Concurrent
541+-- import Control.Concurrent
524−-- import Control.Monad (forever)
542+-- import Control.Monad (forever)
543+-- import Control.Monad.IO.Class (MonadIO(..))
544+-- import Control.Monad.Trans.Class (MonadTrans(lift))
545+-- import Data.Function ((&))
546+-- import Data.Char (toUpper)
547+-- import Prelude hiding (break, map, span, splitAt)
548+-- import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
549+-- import qualified Streamly.Prelude as Stream
550+-- import qualified Streamly.Internal.Data.Stream.IsStream as Stream (parse, foldMany)
551+-- import qualified Streamly.Data.Fold as Fold
552+-- import qualified Streamly.Internal.Data.Fold as Fold
553+-- import qualified Streamly.Internal.Data.Parser as Parser
554+-- import Streamly.Prelude
525-- @
555-- @
526--
556--
527-- To illustrate concurrent vs serial composition aspects, we will use the
557-- To illustrate concurrent vs serial composition aspects, we will use the
@@ -529,10 +559,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
529-- seconds. After the delay it prints the number of seconds it slept.
559-- seconds. After the delay it prints the number of seconds it slept.
530--
560--
531-- @
561-- @
562+-- >>> :{
532−-- delay n = S.'fromEffect' $ do
563+-- delay n = Stream.fromEffect $ do
533−-- threadDelay (n * 1000000)
564+-- threadDelay (n * 1000000)
534−-- tid \<- myThreadId
565+-- tid <- myThreadId
535−-- putStrLn (show tid ++ ": Delay " ++ show n)
566+-- putStrLn (show tid ++ ": Delay " ++ show n)
567+-- :}
568+--
536-- @
569-- @
537
570
538-- $serial
571-- $serial
@@ -554,13 +587,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
554-- 3, 4:
587-- 3, 4:
555--
588--
556-- @
589-- @
557−-- main = S.'drain' $ (print 1 |: print 2 |: S.nil) <> (print 3 |: print 4 |: S.nil)
590+-- >>> Stream.drain $ (print 1 |: print 2 |: Stream.nil) <> (print 3 |: print 4 |: Stream.nil)
558−-- @
559−-- @
560-- 1
591-- 1
561-- 2
592-- 2
562-- 3
593-- 3
563-- 4
594-- 4
595+--
564-- @
596-- @
565--
597--
566-- All actions in both the streams are performed serially in the same thread.
598-- All actions in both the streams are performed serially in the same thread.
@@ -568,12 +600,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
568-- same thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
600-- same thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
569--
601--
570-- @
602-- @
571−-- main = S.'drain' $ delay 3 <> delay 2 <> delay 1
603+-- >>> Stream.drain $ delay 3 <> delay 2 <> delay 1
572−-- @
573−-- @
574−-- ThreadId 36: Delay 3
604+-- ThreadId ... Delay 3
575−-- ThreadId 36: Delay 2
605+-- ThreadId ... Delay 2
576−-- ThreadId 36: Delay 1
606+-- ThreadId ... Delay 1
607+--
577-- @
608-- @
578--
609--
579-- The polymorphic version of the binary operation '<>' of the 'Serial' type is
610-- The polymorphic version of the binary operation '<>' of the 'Serial' type is
@@ -581,13 +612,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
581-- irrespective of the type of stream:
612-- irrespective of the type of stream:
582--
613--
583-- @
614-- @
584−-- main = S.'drain' $ (print 1 |: print 2 |: S.nil) \`S.serial` (print 3 |: print 4 |: S.nil)
615+-- >>> Stream.drain $ (print 1 |: print 2 |: Stream.nil) `Stream.serial` (print 3 |: print 4 |: Stream.nil)
616+-- 1
617+-- 2
618+-- 3
619+-- 4
620+--
585-- @
621-- @
586
622
587-- $interleaved
623-- $interleaved
588--
624--
589-- The 'Semigroup' operation '<>' of the 'WSerial' type combines the two
625-- The 'Semigroup' operation '<>' of the 'WSerial' type combines the two
590−-- streams in a /serial breadth first/ manner. We use the 'fromWSerial' type
626+-- streams in a /serial breadth first/ manner. We use the fromWSerial type
591-- combinator to effect 'WSerial' style of composition. We can also use the
627-- combinator to effect 'WSerial' style of composition. We can also use the
592-- 'WSerial' type annotation for the stream to achieve the same effect.
628-- 'WSerial' type annotation for the stream to achieve the same effect.
593--
629--
@@ -598,13 +634,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
598-- The following example prints the sequence 1, 3, 2, 4
634-- The following example prints the sequence 1, 3, 2, 4
599--
635--
600-- @
636-- @
601−-- main = S.'drain' . S.'fromWSerial' $ (print 1 |: print 2 |: S.'nil') <> (print 3 |: print 4 |: S.'nil')
637+-- >>> Stream.drain . Stream.fromWSerial $ (print 1 |: print 2 |: Stream.nil) <> (print 3 |: print 4 |: Stream.nil)
602−-- @
603−-- @
604-- 1
638-- 1
605-- 3
639-- 3
606-- 2
640-- 2
607-- 4
641-- 4
642+--
608-- @
643-- @
609--
644--
610-- Even though the monadic actions of the two streams are performed in an
645-- Even though the monadic actions of the two streams are performed in an
@@ -613,27 +648,25 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
613-- thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
648-- thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
614--
649--
615-- @
650-- @
616−-- main = S.'drain' . S.'fromWSerial' $ delay 3 <> delay 2 <> delay 1
651+-- >>> Stream.drain . Stream.fromWSerial $ delay 3 <> delay 2 <> delay 1
617−-- @
618−-- @
619−-- ThreadId 36: Delay 3
652+-- ThreadId ...: Delay 3
620−-- ThreadId 36: Delay 2
653+-- ThreadId ...: Delay 2
621−-- ThreadId 36: Delay 1
654+-- ThreadId ...: Delay 1
655+--
622-- @
656-- @
623--
657--
624-- The polymorphic version of the 'WSerial' binary operation '<>' is called
658-- The polymorphic version of the 'WSerial' binary operation '<>' is called
625-- 'wSerial'. We can use 'wSerial' to join streams in an interleaved manner
659-- 'wSerial'. We can use 'wSerial' to join streams in an interleaved manner
626−-- irrespective of the type, notice that we have not used the 'fromWSerial'
660+-- irrespective of the type, notice that we have not used the fromWSerial
627-- combinator in the following example:
661-- combinator in the following example:
628--
662--
629-- @
663-- @
630−-- main = S.'drain' $ (print 1 |: print 2 |: S.'nil') \`S.wSerial` (print 3 |: print 4 |: S.'nil')
664+-- >>> Stream.drain $ (print 1 |: print 2 |: Stream.nil) `Stream.wSerial` (print 3 |: print 4 |: Stream.nil)
631−-- @
632−-- @
633-- 1
665-- 1
634-- 3
666-- 3
635-- 2
667-- 2
636-- 4
668-- 4
669+--
637-- @
670-- @
638--
671--
639-- Note that this composition cannot be used to fold infinite number of streams
672-- Note that this composition cannot be used to fold infinite number of streams
@@ -656,13 +689,14 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
656-- though each action in each stream takes one second:
689-- though each action in each stream takes one second:
657--
690--
658-- @
691-- @
692+-- >>> p n = threadDelay 1000000 >> return n
693+-- >>> :{
659−-- main = do
694+-- do
660−-- xs \<- S.'toList' . S.'fromAhead' $ (p 1 |: p 2 |: S.nil) <> (p 3 |: p 4 |: S.nil)
695+-- xs <- Stream.toList . Stream.fromAhead $ (p 1 |: p 2 |: Stream.nil) <> (p 3 |: p 4 |: Stream.nil)
661−-- print xs
696+-- print xs
662−-- where p n = threadDelay 1000000 >> return n
697+-- :}
663−-- @
664−-- @
665-- [1,2,3,4]
698-- [1,2,3,4]
699+--
666-- @
700-- @
667--
701--
668-- Each stream is constructed 'aheadly' and then both the streams are merged
702-- Each stream is constructed 'aheadly' and then both the streams are merged
@@ -693,13 +727,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
693-- The results are not guaranteed to be in any particular order:
727-- The results are not guaranteed to be in any particular order:
694--
728--
695-- @
729-- @
730+-- p n = threadDelay 1000000 >> return n
696−-- main = do
731+-- do
697−-- xs \<- S.'toList' . S.'fromAsync' $ (p 1 |: p 2 |: S.'nil') <> (p 3 |: p 4 |: S.'nil')
732+-- xs <- Stream.toList . Stream.fromAsync $ (p 1 |: p 2 |: Stream.nil) <> (p 3 |: p 4 |: Stream.nil)
698-- print xs
733-- print xs
699−-- where p n = threadDelay 1000000 >> return n
734+--
700−-- @
701−-- @
702−-- [4,2,1,3]
735+-- [1,3,4,2]
703-- @
736-- @
704--
737--
705-- The constituent streams are also composed in 'Async' manner and the
738-- The constituent streams are also composed in 'Async' manner and the
@@ -708,13 +741,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
708-- The elements in the serial streams would be in serial order in the results:
741-- The elements in the serial streams would be in serial order in the results:
709--
742--
710-- @
743-- @
711−-- main = do
712−-- xs \<- S.'toList' . S.'fromAsync' $ (S.'fromSerial' $ p 1 |: p 2 |: S.'nil') <> (fromSerial $ p 3 |: p 4 |: S.'nil')
713−-- print xs
714−-- where p n = threadDelay 1000000 >> return n
744+-- > p n = threadDelay 1000000 >> return n
715−-- @
745+-- > Stream.toList . Stream.fromAsync $ (Stream.fromSerial $ p 1 |: p 2 |: Stream.nil) <> (fromSerial $ p 3 |: p 4 |: Stream.nil)
716−-- @
746+-- [1,3,4,2] -- order is not predictable
717−-- [3,1,2,4]
747+--
718-- @
748-- @
719--
749--
720-- In the following example we can see that new threads are started when a
750-- In the following example we can see that new threads are started when a
@@ -723,12 +753,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
723-- (3, 2, 1) = 3@ seconds:
753-- (3, 2, 1) = 3@ seconds:
724--
754--
725-- @
755-- @
726−-- main = S.'drain' . S.'fromAsync' $ delay 3 '<>' delay 2 '<>' delay 1
756+-- >>> Stream.drain . Stream.fromAsync $ delay 3 <> delay 2 <> delay 1
727−-- @
728−-- @
729−-- ThreadId 42: Delay 1
757+-- ThreadId ...: Delay 1
730−-- ThreadId 41: Delay 2
758+-- ThreadId ...: Delay 2
731−-- ThreadId 40: Delay 3
759+-- ThreadId ...: Delay 3
760+--
732-- @
761-- @
733--
762--
734-- When we have a tree of computations composed using this style, the tree is
763-- When we have a tree of computations composed using this style, the tree is
@@ -742,13 +771,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
742-- second as all of the actions are concurrent.
771-- second as all of the actions are concurrent.
743--
772--
744-- @
773-- @
745−-- main = S.'drain' . S.'fromAsync' $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
774+-- >>> Stream.drain . Stream.fromAsync $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
746−-- @
775+-- ThreadId ...: Delay 1
747−-- @
776+-- ThreadId ...: Delay 2
748−-- 1
777+-- ThreadId ...: Delay 3
749−-- 2
778+-- ThreadId ...: Delay 4
750−-- 3
779+--
751−-- 4
752-- @
780-- @
753--
781--
754-- All the computations may even run in a single thread when more threads are
782-- All the computations may even run in a single thread when more threads are
@@ -759,8 +787,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
759-- even if none of them blocks:
787-- even if none of them blocks:
760--
788--
761-- @
789-- @
762−-- main = S.'drain' . S.'fromAsync' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
790+-- main = Stream.'drain' . Stream.'fromAsync' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
763−-- where traced m = S.'fromEffect' (myThreadId >>= print) >> return m
791+-- where traced m = Stream.'fromEffect' (myThreadId >>= print) >> return m
764-- @
792-- @
765-- @
793-- @
766-- ThreadId 40
794-- ThreadId 40
@@ -777,12 +805,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
777-- not used the 'fromAsync' combinator in the following example:
805-- not used the 'fromAsync' combinator in the following example:
778--
806--
779-- @
807-- @
780−-- main = S.'drain' $ delay 3 \`S.'async'` delay 2 \`S.'async'` delay 1
808+-- >>> Stream.drain $ delay 3 `Stream.async` delay 2 `Stream.async` delay 1
781−-- @
782−-- @
783−-- ThreadId 42: Delay 1
809+-- ThreadId ...: Delay 1
784−-- ThreadId 41: Delay 2
810+-- ThreadId ...: Delay 2
785−-- ThreadId 40: Delay 3
811+-- ThreadId ...: Delay 3
812+--
786-- @
813-- @
787--
814--
788-- Since the concurrency provided by this operator is demand driven it cannot
815-- Since the concurrency provided by this operator is demand driven it cannot
@@ -820,13 +847,16 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
820-- first traversal order but this is not guaranteed.
847-- first traversal order but this is not guaranteed.
821--
848--
822-- @
849-- @
850+-- >>> :{
851+-- do
852+-- hSetBuffering stdout LineBuffering
823−-- main = S.'drain' . S.'fromWAsync' $ (S.'fromSerial' $ print 1 |: print 2 |: S.'nil') <> (S.'fromSerial' $ print 3 |: print 4 |: S.'nil')
853+-- Stream.drain . Stream.fromWAsync $ (Stream.fromSerial $ print 1 |: print 2 |: Stream.nil) <> (Stream.fromSerial $ print 3 |: print 4 |: Stream.nil)
824−-- @
854+-- :}
825−-- @
826-- 1
855-- 1
827-- 3
856-- 3
828-- 2
857-- 2
829-- 4
858-- 4
859+--
830-- @
860-- @
831--
861--
832-- The polymorphic version of the binary operation '<>' of the 'WAsync' type is
862-- The polymorphic version of the binary operation '<>' of the 'WAsync' type is
@@ -835,12 +865,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
835-- the 'fromWAsync' combinator in the following example:
865-- the 'fromWAsync' combinator in the following example:
836--
866--
837-- @
867-- @
838−-- main = S.'drain' $ delay 3 \S.`wAsync` delay 2 \S.`wAsync` delay 1
868+-- >>> Stream.drain $ delay 3 `Stream.wAsync` delay 2 `Stream.wAsync` delay 1
839−-- @
840−-- @
841−-- ThreadId 42: Delay 1
869+-- ThreadId ...: Delay 1
842−-- ThreadId 41: Delay 2
870+-- ThreadId ...: Delay 2
843−-- ThreadId 40: Delay 3
871+-- ThreadId ...: Delay 3
872+--
844-- @
873-- @
845--
874--
846-- Since the concurrency provided by this style is demand driven it may not
875-- Since the concurrency provided by this style is demand driven it may not
@@ -874,15 +903,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
874-- package to run this example:
903-- package to run this example:
875--
904--
876-- @
905-- @
877−-- import qualified Streamly.Prelude as S
906+-- import qualified Streamly.Prelude as Stream
878-- import Network.HTTP.Simple
907-- import Network.HTTP.Simple
879--
908--
880−-- main = S.'drain' . S.'fromParallel' $ google \<> bing \<> duckduckgo
909+-- main = Stream.'drain' . Stream.'fromParallel' $ google \<> bing \<> duckduckgo
881-- where
910-- where
882-- google = get "https://www.google.com/search?q=haskell"
911-- google = get "https://www.google.com/search?q=haskell"
883-- bing = get "https://www.bing.com/search?q=haskell"
912-- bing = get "https://www.bing.com/search?q=haskell"
884-- duckduckgo = get "https://www.duckduckgo.com/?q=haskell"
913-- duckduckgo = get "https://www.duckduckgo.com/?q=haskell"
885−-- get s = S.'fromEffect' (httpNoBody (parseRequest_ s) >> putStrLn (show s))
914+-- get s = Stream.'fromEffect' (httpNoBody (parseRequest_ s) >> putStrLn (show s))
886-- @
915-- @
887--
916--
888-- The polymorphic version of the binary operation '<>' of the 'Parallel' type
917-- The polymorphic version of the binary operation '<>' of the 'Parallel' type
@@ -891,12 +920,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
891-- 'fromParallel' combinator in the following example:
920-- 'fromParallel' combinator in the following example:
892--
921--
893-- @
922-- @
894−-- main = S.'drain' $ delay 3 \`S.'parallel'` delay 2 \`S.'wAsync'` delay 1
923+-- >>> Stream.drain $ delay 3 `Stream.parallel` delay 2 `Stream.wAsync` delay 1
895−-- @
896−-- @
897−-- ThreadId 42: Delay 1
924+-- ThreadId ...: Delay 1
898−-- ThreadId 41: Delay 2
925+-- ThreadId ...: Delay 2
899−-- ThreadId 40: Delay 3
926+-- ThreadId ...: Delay 3
927+--
900-- @
928-- @
901--
929--
902-- Note that this style of composition cannot be used to combine infinite
930-- Note that this style of composition cannot be used to combine infinite
@@ -933,15 +961,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
933-- second:
961-- second:
934--
962--
935-- @
963-- @
936−-- import qualified "Streamly.Prelude" as S
964+-- import qualified "Streamly.Prelude" as Stream
937-- import Control.Concurrent
965-- import Control.Concurrent
938--
966--
939-- main = do
967-- main = do
940−-- S.'drain' $ S.'fromAsync' $ foldMap delay [1..10]
968+-- Stream.'drain' $ Stream.'fromAsync' $ foldMap delay [1..10]
941−-- S.'drain' $ S.'concatFoldableWith' S.'async' (map delay [1..10])
969+-- Stream.'drain' $ Stream.'concatFoldableWith' Stream.'async' (map delay [1..10])
942−-- S.'drain' $ S.'concatMapFoldableWith' S.'async' delay [1..10]
970+-- Stream.'drain' $ Stream.'concatMapFoldableWith' Stream.'async' delay [1..10]
943−-- S.'drain' $ S.'concatForFoldableWith' S.'async' [1..10] delay
971+-- Stream.'drain' $ Stream.'concatForFoldableWith' Stream.'async' [1..10] delay
944−-- where delay n = S.'fromEffect' $ threadDelay (n * 1000000) >> print n
972+-- where delay n = Stream.'fromEffect' $ threadDelay (n * 1000000) >> print n
945-- @
973-- @
946
974
947-- $nesting
975-- $nesting
@@ -986,16 +1014,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
986-- instead.
1014-- instead.
987--
1015--
988-- @
1016-- @
989−-- import qualified "Streamly.Prelude" as S
1017+-- >>> :{
990−--
991−-- main = S.'drain' $ do
1018+-- Stream.drain $ do
992−-- x <- S.'fromFoldable' [3,2,1]
1019+-- x <- Stream.fromFoldable [3,2,1]
993-- delay x
1020-- delay x
994−-- @
1021+-- :}
995−-- @
996−-- ThreadId 30: Delay 3
1022+-- ThreadId ...: Delay 3
997−-- ThreadId 30: Delay 2
1023+-- ThreadId ...: Delay 2
998−-- ThreadId 30: Delay 1
1024+-- ThreadId ...: Delay 1
1025+--
999-- @
1026-- @
1000--
1027--
1001-- As we can see, the code after the @fromFoldable@ statement is run three
1028-- As we can see, the code after the @fromFoldable@ statement is run three
@@ -1007,11 +1034,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1007-- written like this:
1034-- written like this:
1008--
1035--
1009-- @
1036-- @
1010−-- import qualified "Streamly.Prelude" as S
1011−--
1012−-- import Control.Monad (forever)
1013−--
1014−-- main = S.'drain' $ forever $ S.'fromEffect' getLine >>= S.'fromEffect' . putStrLn
1037+-- main = Stream.'drain' $ forever $ Stream.'fromEffect' getLine >>= Stream.'fromEffect' . putStrLn
1015-- @
1038-- @
1016--
1039--
1017-- When multiple streams are composed using this style they nest in a DFS
1040-- When multiple streams are composed using this style they nest in a DFS
@@ -1020,18 +1043,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1020-- loops in imperative programming.
1043-- loops in imperative programming.
1021--
1044--
1022-- @
1045-- @
1023−-- import qualified "Streamly.Prelude" as S
1046+-- >>> :{
1024−--
1025−-- main = S.'drain' $ do
1047+-- Stream.drain $ do
1026−-- x <- S.'fromFoldable' [1,2]
1048+-- x <- Stream.fromFoldable [1,2]
1027−-- y <- S.'fromFoldable' [3,4]
1049+-- y <- Stream.fromFoldable [3,4]
1028−-- S.'fromEffect' $ putStrLn $ show (x, y)
1050+-- Stream.fromEffect $ putStrLn $ show (x, y)
1029−-- @
1051+-- :}
1030−-- @
1031-- (1,3)
1052-- (1,3)
1032-- (1,4)
1053-- (1,4)
1033-- (2,3)
1054-- (2,3)
1034-- (2,4)
1055-- (2,4)
1056+--
1035-- @
1057-- @
1036--
1058--
1037-- Notice that this is analogous to merging streams of type 'Serial' or merging
1059-- Notice that this is analogous to merging streams of type 'Serial' or merging
@@ -1048,19 +1070,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1048-- type of the stream as 'Ahead'.
1070-- type of the stream as 'Ahead'.
1049--
1071--
1050-- @
1072-- @
1051−-- import qualified "Streamly.Prelude" as S
1073+-- >>> :{
1052−--
1053−-- comp = S.'toList' . S.'fromAhead' $ do
1074+-- comp = Stream.toList . Stream.fromAhead $ do
1054−-- x <- S.'fromFoldable' [3,2,1]
1075+-- x <- Stream.fromFoldable [3,2,1]
1055−-- delay x >> return x
1076+-- delay x >> return x
1077+-- :}
1056--
1078--
1057−-- main = comp >>= print
1079+-- >>> comp >>= print
1058−-- @
1059−-- @
1060−-- ThreadId 40: Delay 1
1080+-- ThreadId ...: Delay 1
1061−-- ThreadId 39: Delay 2
1081+-- ThreadId ...: Delay 2
1062−-- ThreadId 38: Delay 3
1082+-- ThreadId ...: Delay 3
1063-- [3,2,1]
1083-- [3,2,1]
1084+--
1064-- @
1085-- @
1065--
1086--
1066-- This code finishes in 3 seconds, 'Serial' would take 6 seconds. As we can
1087-- This code finishes in 3 seconds, 'Serial' would take 6 seconds. As we can
@@ -1088,16 +1109,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1088-- type of the stream as 'Async'.
1109-- type of the stream as 'Async'.
1089--
1110--
1090-- @
1111-- @
1091−-- import qualified "Streamly.Prelude" as S
1112+-- >>> :{
1113+-- Stream.drain . Stream.fromAsync $ do
1114+-- x <- Stream.fromFoldable [3,2,1]
1115+-- delay x
1116+-- :}
1117+-- ThreadId ...: Delay 1
1118+-- ThreadId ...: Delay 2
1119+-- ThreadId ...: Delay 3
1092--
1120--
1093−-- main = S.'drain' . S.'fromAsync' $ do
1094−-- x <- S.'fromFoldable' [3,2,1]
1095−-- delay x
1096−-- @
1097−-- @
1098−-- ThreadId 40: Delay 1
1099−-- ThreadId 39: Delay 2
1100−-- ThreadId 38: Delay 3
1101-- @
1121-- @
1102--
1122--
1103-- As we can see the code after the @fromFoldable@ statement is run three
1123-- As we can see the code after the @fromFoldable@ statement is run three
@@ -1114,18 +1134,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1114-- on the demand from the consumer of the stream.
1134-- on the demand from the consumer of the stream.
1115--
1135--
1116-- @
1136-- @
1117−-- import qualified "Streamly.Prelude" as S
1118--
1137--
1119−-- main = S.'drain' . S.'fromAsync' $ do
1138+-- Stream.drain . Stream.fromAsync $ do
1120−-- x <- S.'fromFoldable' [1,2]
1139+-- x <- Stream.fromFoldable [1,2]
1121−-- y <- S.'fromFoldable' [3,4]
1140+-- y <- Stream.fromFoldable [3,4]
1122−-- S.'fromEffect' $ putStrLn $ show (x, y)
1141+-- Stream.fromEffect $ putStrLn $ show (x, y)
1123−-- @
1142+--
1124−-- @
1125-- (1,3)
1143-- (1,3)
1126-- (1,4)
1144-- (1,4)
1127-- (2,3)
1145-- (2,3)
1128-- (2,4)
1146-- (2,4)
1147+--
1129-- @
1148-- @
1130
1149
1131-- $interleavedNesting
1150-- $interleavedNesting
@@ -1133,23 +1152,22 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1133-- The 'Monad' composition of 'WSerial' type interleaves the iterations of
1152-- The 'Monad' composition of 'WSerial' type interleaves the iterations of
1134-- outer and inner loops in a nested loop composition. This works exactly the
1153-- outer and inner loops in a nested loop composition. This works exactly the
1135-- same way as the merging of two streams in 'wSerially' fashion works. The
1154-- same way as the merging of two streams in 'wSerially' fashion works. The
1136−-- 'fromWSerial' type combinator can be used to switch to this style of
1155+-- fromWSerial type combinator can be used to switch to this style of
1137-- composition. Alternatively, a type annotation can be used to specify the
1156-- composition. Alternatively, a type annotation can be used to specify the
1138-- type of the stream as 'WSerial'.
1157-- type of the stream as 'WSerial'.
1139--
1158--
1140-- @
1159-- @
1141−-- import qualified "Streamly.Prelude" as S
1160+-- >>> :{
1142−--
1143−-- main = S.'drain' . S.'fromWSerial' $ do
1161+-- Stream.drain . Stream.fromWSerial $ do
1144−-- x <- S.'fromFoldable' [1,2]
1162+-- x <- Stream.fromFoldable [1,2]
1145−-- y <- S.'fromFoldable' [3,4]
1163+-- y <- Stream.fromFoldable [3,4]
1146−-- S.fromEffect $ putStrLn $ show (x, y)
1164+-- Stream.fromEffect $ putStrLn $ show (x, y)
1147−-- @
1165+-- :}
1148−-- @
1149-- (1,3)
1166-- (1,3)
1150-- (2,3)
1167-- (2,3)
1151-- (1,4)
1168-- (1,4)
1152-- (2,4)
1169-- (2,4)
1170+--
1153-- @
1171-- @
1154--
1172--
1155
1173
@@ -1165,18 +1183,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1165-- specify the type of the stream as 'WAsync'.
1183-- specify the type of the stream as 'WAsync'.
1166--
1184--
1167-- @
1185-- @
1168−-- import qualified "Streamly.Prelude" as S
1186+-- >>> :{
1169−--
1170−-- main = S.'drain' . S.'fromWAsync' $ do
1187+-- Stream.drain . Stream.fromWAsync $ do
1171−-- x <- S.'fromFoldable' [1,2]
1188+-- x <- Stream.delay 1 $ Stream.fromFoldable [1,2]
1172−-- y <- S.'fromFoldable' [3,4]
1189+-- y <- Stream.delay 1 $ Stream.fromFoldable [3,4]
1173−-- S.'fromEffect' $ putStrLn $ show (x, y)
1190+-- Stream.fromEffect $ putStrLn $ show (x, y)
1174−-- @
1191+-- :}
1175−-- @
1176-- (1,3)
1192-- (1,3)
1177−-- (2,3)
1193+-- ...
1178−-- (1,4)
1194+-- ...
1179-- (2,4)
1195-- (2,4)
1196+--
1180-- @
1197-- @
1181
1198
1182-- $parallelNesting
1199-- $parallelNesting
@@ -1190,16 +1207,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1190-- annotation can be used to specify the type of the stream as 'Parallel'.
1207-- annotation can be used to specify the type of the stream as 'Parallel'.
1191--
1208--
1192-- @
1209-- @
1193−-- import qualified "Streamly.Prelude" as S
1210+-- >>> :{
1211+-- Stream.drain . Stream.fromParallel $ do
1212+-- x <- Stream.fromFoldable [3,2,1]
1213+-- delay x
1214+-- :}
1215+-- ThreadId ...: Delay 1
1216+-- ThreadId ...: Delay 2
1217+-- ThreadId ...: Delay 3
1194--
1218--
1195−-- main = S.'drain' . S.'fromParallel' $ do
1196−-- x <- S.'fromFoldable' [3,2,1]
1197−-- delay x
1198−-- @
1199−-- @
1200−-- ThreadId 40: Delay 1
1201−-- ThreadId 39: Delay 2
1202−-- ThreadId 38: Delay 3
1203-- @
1219-- @
1204
1220
1205-- $monadExercise
1221-- $monadExercise
@@ -1210,30 +1226,28 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1210-- specific mode of composition. For example take a look at the following code.
1226-- specific mode of composition. For example take a look at the following code.
1211--
1227--
1212-- @
1228-- @
1213−-- import qualified "Streamly.Prelude" as S
1214−--
1215−-- composed :: (S.IsStream t, Monad (t IO)) => t IO ()
1229+-- composed :: (Stream.IsStream t, Monad (t IO)) => t IO ()
1216-- composed = do
1230-- composed = do
1217-- sz <- sizes
1231-- sz <- sizes
1218-- cl <- colors
1232-- cl <- colors
1219-- sh <- shapes
1233-- sh <- shapes
1220−-- S.'fromEffect' $ putStrLn $ show (sz, cl, sh)
1234+-- Stream.'fromEffect' $ putStrLn $ show (sz, cl, sh)
1221--
1235--
1222-- where
1236-- where
1223--
1237--
1224−-- sizes = S.'fromFoldable' [1, 2, 3]
1238+-- sizes = Stream.'fromFoldable' [1, 2, 3]
1225−-- colors = S.'fromFoldable' ["red", "green", "blue"]
1239+-- colors = Stream.'fromFoldable' ["red", "green", "blue"]
1226−-- shapes = S.'fromFoldable' ["triangle", "square", "circle"]
1240+-- shapes = Stream.'fromFoldable' ["triangle", "square", "circle"]
1227-- @
1241-- @
1228--
1242--
1229-- Now we can interpret this in whatever way we want:
1243-- Now we can interpret this in whatever way we want:
1230--
1244--
1231-- @
1245-- @
1232−-- main = S.'drain' . S.'fromSerial' $ composed
1246+-- main = Stream.'drain' . Stream.'fromSerial' $ composed
1233−-- main = S.'drain' . S.'fromWSerial' $ composed
1247+-- main = Stream.'drain' . Stream.'fromWSerial' $ composed
1234−-- main = S.'drain' . S.'fromAsync' $ composed
1248+-- main = Stream.'drain' . Stream.'fromAsync' $ composed
1235−-- main = S.'drain' . S.'fromWAsync' $ composed
1249+-- main = Stream.'drain' . Stream.'fromWAsync' $ composed
1236−-- main = S.'drain' . S.'fromParallel' $ composed
1250+-- main = Stream.'drain' . Stream.'fromParallel' $ composed
1237-- @
1251-- @
1238--
1252--
1239-- As an exercise try to figure out the output of this code for each mode of
1253-- As an exercise try to figure out the output of this code for each mode of
@@ -1246,9 +1260,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1246-- serial.
1260-- serial.
1247--
1261--
1248-- @
1262-- @
1249−-- import qualified "Streamly.Prelude" as S
1263+-- >>> (Stream.toList $ fmap show $ Stream.fromFoldable [1..10]) >>= print
1264+-- ["1","2","3","4","5","6","7","8","9","10"]
1250--
1265--
1251−-- main = (S.'toList' $ fmap show $ S.'fromFoldable' [1..10]) >>= print
1252-- @
1266-- @
1253--
1267--
1254-- Also see functions 'mapM' and 'sequence' from "Streamly.Prelude" module
1268-- Also see functions 'mapM' and 'sequence' from "Streamly.Prelude" module
@@ -1264,46 +1278,41 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1264-- serially and takes a total 17 seconds (1 + 3 + 4 + 2 + 3 + 4):
1278-- serially and takes a total 17 seconds (1 + 3 + 4 + 2 + 3 + 4):
1265--
1279--
1266-- @
1280-- @
1267−-- import qualified "Streamly.Prelude" as S
1281+-- >>> d n = delay n >> return n
1268−-- import Control.Concurrent
1282+-- >>> s1 = d 1 <> d 2
1283+-- >>> s2 = d 3 <> d 4
1269--
1284--
1270−-- s1 = d 1 <> d 2
1271−-- s2 = d 3 <> d 4
1272−-- d n = delay n >> return n
1273−--
1274−-- main = (S.'toList' . S.'fromSerial' $ (,) \<$> s1 \<*> s2) >>= print
1285+-- >>> (Stream.toList . Stream.fromSerial $ (,) <$> s1 <*> s2) >>= print
1275−-- @
1276−-- @
1277−-- ThreadId 36: Delay 1
1286+-- ThreadId ...: Delay 1
1278−-- ThreadId 36: Delay 3
1287+-- ThreadId ...: Delay 3
1279−-- ThreadId 36: Delay 4
1288+-- ThreadId ...: Delay 4
1280−-- ThreadId 36: Delay 2
1289+-- ThreadId ...: Delay 2
1281−-- ThreadId 36: Delay 3
1290+-- ThreadId ...: Delay 3
1282−-- ThreadId 36: Delay 4
1291+-- ThreadId ...: Delay 4
1283-- [(1,3),(1,4),(2,3),(2,4)]
1292-- [(1,3),(1,4),(2,3),(2,4)]
1293+--
1284-- @
1294-- @
1285--
1295--
1286-- Similarly 'WSerial' applicative runs the iterations in an interleaved
1296-- Similarly 'WSerial' applicative runs the iterations in an interleaved
1287-- order but since it is serial it takes a total of 17 seconds:
1297-- order but since it is serial it takes a total of 17 seconds:
1288--
1298--
1289-- @
1299-- @
1290−-- main = (S.'toList' . S.'fromWSerial' $ (,) \<$> s1 \<*> s2) >>= print
1300+-- >>> (Stream.toList . Stream.fromWSerial $ (,) <$> s1 <*> s2) >>= print
1291−-- @
1292−-- @
1293−-- ThreadId 36: Delay 1
1301+-- ThreadId ...: Delay 1
1294−-- ThreadId 36: Delay 3
1302+-- ThreadId ...: Delay 3
1295−-- ThreadId 36: Delay 2
1303+-- ThreadId ...: Delay 2
1296−-- ThreadId 36: Delay 3
1304+-- ThreadId ...: Delay 3
1297−-- ThreadId 36: Delay 4
1305+-- ThreadId ...: Delay 4
1298−-- ThreadId 36: Delay 4
1306+-- ThreadId ...: Delay 4
1299-- [(1,3),(2,3),(1,4),(2,4)]
1307-- [(1,3),(2,3),(1,4),(2,4)]
1308+--
1300-- @
1309-- @
1301--
1310--
1302-- 'Async' can run the iterations concurrently and therefore takes a total
1311-- 'Async' can run the iterations concurrently and therefore takes a total
1303-- of 6 seconds which is max (1, 2) + max (3, 4):
1312-- of 6 seconds which is max (1, 2) + max (3, 4):
1304--
1313--
1305-- @
1314-- @
1306−-- main = (S.'toList' . S.'fromAsync' $ (,) \<$> s1 \<*> s2) >>= print
1315+-- main = (Stream.'toList' . Stream.'fromAsync' $ (,) \<$> s1 \<*> s2) >>= print
1307-- @
1316-- @
1308-- @
1317-- @
1309-- ThreadId 34: Delay 1
1318-- ThreadId 34: Delay 1
@@ -1319,7 +1328,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1319-- therefore takes a total of 6 seconds (2 + 4):
1328-- therefore takes a total of 6 seconds (2 + 4):
1320--
1329--
1321-- @
1330-- @
1322−-- main = (S.'toList' . S.'fromWAsync' $ (,) \<$> s1 \<*> s2) >>= print
1331+-- main = (Stream.'toList' . Stream.'fromWAsync' $ (,) \<$> s1 \<*> s2) >>= print
1323-- @
1332-- @
1324-- @
1333-- @
1325-- ThreadId 34: Delay 1
1334-- ThreadId 34: Delay 1
@@ -1347,26 +1356,27 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1347-- zip composition:
1356-- zip composition:
1348--
1357--
1349-- @
1358-- @
1350−-- import qualified "Streamly.Prelude" as S
1351−-- import Control.Concurrent
1352--
1359--
1353-- d n = delay n >> return n
1360-- d n = delay n >> return n
1354−-- s1 = S.'fromSerial' $ d 1 <> d 2
1361+-- s1 = Stream.'fromSerial' $ d 1 <> d 2
1355−-- s2 = S.'fromSerial' $ d 3 <> d 4
1362+-- s2 = Stream.'fromSerial' $ d 3 <> d 4
1356--
1363--
1357−-- main = (S.'toList' . S.'fromZipSerial' $ (,) \<$> s1 \<*> s2) >>= print
1364+-- main = (Stream.'toList' . Stream.'fromZipSerial' $ (,) \<$> s1 \<*> s2) >>= print
1358-- @
1365-- @
1359--
1366--
1360-- This takes total 10 seconds to zip, which is (1 + 2 + 3 + 4) since
1367-- This takes total 10 seconds to zip, which is (1 + 2 + 3 + 4) since
1361-- everything runs serially:
1368-- everything runs serially:
1362--
1369--
1363−-- @
1370+-- >>> d n = delay n >> return n
1371+-- >>> s1 = Stream.fromSerial $ d 1 <> d 2
1372+-- >>> s2 = Stream.fromSerial $ d 3 <> d 4
1373+-- >>> (Stream.toList . Stream.fromZipSerial $ (,) <$> s1 <*> s2) >>= print
1364−-- ThreadId 29: Delay 1
1374+-- ThreadId ...: Delay 1
1365−-- ThreadId 29: Delay 3
1375+-- ThreadId ...: Delay 3
1366−-- ThreadId 29: Delay 2
1376+-- ThreadId ...: Delay 2
1367−-- ThreadId 29: Delay 4
1377+-- ThreadId ...: Delay 4
1368-- [(1,3),(2,4)]
1378-- [(1,3),(2,4)]
1369−-- @
1379+--
1370
1380
1371-- $parallelzip
1381-- $parallelzip
1372--
1382--
@@ -1376,29 +1386,35 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1376--
1386--
1377--
1387--
1378-- @
1388-- @
1379−-- import qualified "Streamly.Prelude" as S
1380−-- import Control.Concurrent
1381-- import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
1389-- import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
1382--
1390--
1383-- d n = delay n >> return n
1391-- d n = delay n >> return n
1384−-- s1 = S.'fromSerial' $ d 1 <> d 2
1392+-- s1 = Stream.'fromSerial' $ d 1 <> d 2
1385−-- s2 = S.'fromSerial' $ d 3 <> d 4
1393+-- s2 = Stream.'fromSerial' $ d 3 <> d 4
1386--
1394--
1387-- main = do
1395-- main = do
1388-- hSetBuffering stdout LineBuffering
1396-- hSetBuffering stdout LineBuffering
1389−-- (S.'toList' . S.'fromZipAsync' $ (,) \<$> s1 \<*> s2) >>= print
1397+-- (Stream.'toList' . Stream.'fromZipAsync' $ (,) \<$> s1 \<*> s2) >>= print
1390-- @
1398-- @
1391--
1399--
1392-- This takes 7 seconds to zip, which is max (1,3) + max (2,4) because 1 and 3
1400-- This takes 7 seconds to zip, which is max (1,3) + max (2,4) because 1 and 3
1393-- are produced concurrently, and 2 and 4 are produced concurrently:
1401-- are produced concurrently, and 2 and 4 are produced concurrently:
1394--
1402--
1395−-- @
1403+-- >>> d n = delay n >> return n
1404+-- >>> s1 = Stream.fromSerial $ d 1 <> d 2
1405+-- >>> s2 = Stream.fromSerial $ d 3 <> d 4
1406+--
1407+-- >>> :{
1408+-- do
1409+-- hSetBuffering stdout LineBuffering
1410+-- (Stream.toList . Stream.fromZipAsync $ (,) <$> s1 <*> s2) >>= print
1411+-- :}
1396−-- ThreadId 32: Delay 1
1412+-- ThreadId ...: Delay 1
1397−-- ThreadId 32: Delay 2
1413+-- ThreadId ...: Delay 2
1398−-- ThreadId 33: Delay 3
1414+-- ThreadId ...: Delay 3
1399−-- ThreadId 33: Delay 4
1415+-- ThreadId ...: Delay 4
1400-- [(1,3),(2,4)]
1416-- [(1,3),(2,4)]
1401−-- @
1417+--
1402
1418
1403-- $concurrent
1419-- $concurrent
1404--
1420--
@@ -1417,16 +1433,16 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1417-- combinator instead of explicitly folding with 'async'.
1433-- combinator instead of explicitly folding with 'async'.
1418--
1434--
1419-- @
1435-- @
1420−-- import qualified "Streamly.Prelude" as S
1436+-- import qualified "Streamly.Prelude" as Stream
1421-- import Data.List (sum)
1437-- import Data.List (sum)
1422--
1438--
1423-- main = do
1439-- main = do
1424−-- z \<- S.'toList'
1440+-- z \<- Stream.'toList'
1425−-- $ S.'fromSerial' -- Serial monadic processing (sqrt below)
1441+-- $ Stream.'fromSerial' -- Serial monadic processing (sqrt below)
1426-- $ do
1442-- $ do
1427−-- x2 \<- S.'concatForFoldableWith' S.'async' [1..100] $ -- Concurrent @"for"@ loop
1443+-- x2 \<- Stream.'concatForFoldableWith' Stream.'async' [1..100] $ -- Concurrent @"for"@ loop
1428-- \\x -> return $ x * x -- body of the loop
1444-- \\x -> return $ x * x -- body of the loop
1429−-- y2 \<- S.'concatForFoldableWith' S.'async' [1..100] $
1445+-- y2 \<- Stream.'concatForFoldableWith' Stream.'async' [1..100] $
1430-- \\y -> return $ y * y
1446-- \\y -> return $ y * y
1431-- return $ sqrt (x2 + y2)
1447-- return $ sqrt (x2 + y2)
1432-- print $ sum z
1448-- print $ sum z
@@ -1459,10 +1475,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1459-- health improves and the game continues.
1475-- health improves and the game continues.
1460--
1476--
1461-- @
1477-- @
1462−-- {-\# LANGUAGE FlexibleContexts #-}
1478+-- {-\# LANGUAGE FlexibleContexts \#-}
1463--
1479--
1464-- import "Streamly.Prelude" (MonadAsync, SerialT)
1480-- import "Streamly.Prelude" (MonadAsync, SerialT)
1465−-- import "Streamly.Prelude" as S
1481+-- import "Streamly.Prelude" as Stream
1466-- import Control.Monad (void)
1482-- import Control.Monad (void)
1467-- import Control.Monad.IO.Class (MonadIO(liftIO))
1483-- import Control.Monad.IO.Class (MonadIO(liftIO))
1468-- import Control.Monad.State (MonadState, get, modify, runStateT)
1484-- import Control.Monad.State (MonadState, get, modify, runStateT)
@@ -1470,7 +1486,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1470-- data Event = Quit | Harm Int | Heal Int deriving (Show)
1486-- data Event = Quit | Harm Int | Heal Int deriving (Show)
1471--
1487--
1472-- userAction :: MonadAsync m => 'SerialT' m Event
1488-- userAction :: MonadAsync m => 'SerialT' m Event
1473−-- userAction = S.'repeatM' $ liftIO askUser
1489+-- userAction = Stream.'repeatM' $ liftIO askUser
1474-- where
1490-- where
1475-- askUser = do
1491-- askUser = do
1476-- command <- getLine
1492-- command <- getLine
@@ -1481,13 +1497,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1481-- _ -> putStrLn "Type potion or harm or quit" >> askUser
1497-- _ -> putStrLn "Type potion or harm or quit" >> askUser
1482--
1498--
1483-- acidRain :: MonadAsync m => 'SerialT' m Event
1499-- acidRain :: MonadAsync m => 'SerialT' m Event
1484−-- acidRain = S.'fromAsync' $ S.'constRate' 1 $ S.'repeatM' $ liftIO $ return $ Harm 1
1500+-- acidRain = Stream.'fromAsync' $ Stream.'constRate' 1 $ Stream.'repeatM' $ liftIO $ return $ Harm 1
1485--
1501--
1486-- data Result = Check | Done
1502-- data Result = Check | Done
1487--
1503--
1488-- runEvents :: (MonadAsync m, MonadState Int m) => 'SerialT' m Result
1504-- runEvents :: (MonadAsync m, MonadState Int m) => 'SerialT' m Result
1489-- runEvents = do
1505-- runEvents = do
1490−-- event \<- userAction \`S.'parallel'` acidRain
1506+-- event \<- userAction \`Stream.'parallel'` acidRain
1491-- case event of
1507-- case event of
1492-- Harm n -> modify (\\h -> h - n) >> return Check
1508-- Harm n -> modify (\\h -> h - n) >> return Check
1493-- Heal n -> modify (\\h -> h + n) >> return Check
1509-- Heal n -> modify (\\h -> h + n) >> return Check
@@ -1507,9 +1523,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1507--
1523--
1508-- main :: IO ()
1524-- main :: IO ()
1509-- main = do
1525-- main = do
1510−-- putStrLn "Your health is deteriorating due to acid rain,\\
1526+-- putStrLn "Your health is deteriorating due to acid rain, type \\\"potion\\\" or \\\"quit\\\""
1511−-- \\ type \\"potion\\" or \\"quit\\""
1512−-- let runGame = S.'drainWhile' (== Alive) $ S.'mapM' getStatus runEvents
1527+-- let runGame = Stream.'drainWhile' (== Alive) $ Stream.'mapM' getStatus runEvents
1513-- void $ runStateT runGame 60
1528-- void $ runStateT runGame 60
1514-- @
1529-- @
1515--
1530--
@@ -1542,102 +1557,102 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1542--
1557--
1543-- @
1558-- @
1544-- import "Streamly.Prelude" (SerialT)
1559-- import "Streamly.Prelude" (SerialT)
1545−-- import qualified "Streamly.Prelude" as S
1560+-- import qualified "Streamly.Prelude" as Stream
1546−-- import qualified Data.Vector.Fusion.Stream.Monadic as V
1561+-- import qualified Data.Vector.Fusion.Stream.Monadic as Vector
1547--
1562--
1548-- -- | vector to streamly
1563-- -- | vector to streamly
1549−-- fromVector :: (S.IsStream t, Monad m) => V.Stream m a -> t m a
1564+-- fromVector :: (Stream.IsStream t, Monad m) => Vector.Stream m a -> t m a
1550−-- fromVector = S.unfoldrM unconsV
1565+-- fromVector = Stream.unfoldrM unconsV
1551-- where
1566-- where
1552-- unconsV v = do
1567-- unconsV v = do
1553−-- r <- V.null v
1568+-- r <- Vector.null v
1554-- if r
1569-- if r
1555-- then return Nothing
1570-- then return Nothing
1556-- else do
1571-- else do
1557−-- h <- V.head v
1572+-- h <- Vector.head v
1558−-- return $ Just (h, V.tail v)
1573+-- return $ Just (h, Vector.tail v)
1559--
1574--
1560-- -- | streamly to vector
1575-- -- | streamly to vector
1561−-- toVector :: Monad m => SerialT m a -> V.Stream m a
1576+-- toVector :: Monad m => SerialT m a -> Vector.Stream m a
1562−-- toVector = V.unfoldrM (S.uncons . S.adapt)
1577+-- toVector = Vector.unfoldrM (Stream.uncons . Stream.adapt)
1563--
1578--
1564-- main = do
1579-- main = do
1565−-- S.toList (fromVector (V.fromList [1..3])) >>= print
1580+-- Stream.toList (fromVector (Vector.fromList [1..3])) >>= print
1566−-- V.toList (toVector (S.fromFoldable [1..3])) >>= print
1581+-- Vector.toList (toVector (Stream.fromFoldable [1..3])) >>= print
1567-- @
1582-- @
1568--
1583--
1569-- Interop with @pipes@:
1584-- Interop with @pipes@:
1570--
1585--
1571-- @
1586-- @
1572-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1587-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1573−-- import qualified "Streamly.Prelude" as S
1588+-- import qualified "Streamly.Prelude" as Stream
1574−-- import qualified Pipes as P
1589+-- import qualified Pipes as Pipe
1575−-- import qualified Pipes.Prelude as P
1590+-- import qualified Pipes.Prelude as Pipe
1576--
1591--
1577-- -- | pipes to streamly
1592-- -- | pipes to streamly
1578−-- fromPipes :: (IsStream t, MonadAsync m) => P.Producer a m () -> t m a
1593+-- fromPipes :: (IsStream t, MonadAsync m) => Pipe.Producer a m () -> t m a
1579−-- fromPipes = S.'unfoldrM' unconsP
1594+-- fromPipes = Stream.'unfoldrM' unconsP
1580-- where
1595-- where
1581−-- -- Adapt P.next to return a Maybe instead of Either
1596+-- -- Adapt Pipe.next to return a Maybe instead of Either
1582−-- unconsP p = either (const Nothing) Just <$> P.next p
1597+-- unconsP p = either (const Nothing) Just <$> Pipe.next p
1583--
1598--
1584-- -- | streamly to pipes
1599-- -- | streamly to pipes
1585−-- toPipes :: Monad m => SerialT m a -> P.Producer a m ()
1600+-- toPipes :: Monad m => SerialT m a -> Pipe.Producer a m ()
1586−-- toPipes = P.unfoldr unconsEither
1601+-- toPipes = Pipe.unfoldr unconsEither
1587-- where
1602-- where
1588−-- -- Adapt S.uncons to return an Either instead of Maybe
1603+-- -- Adapt Stream.uncons to return an Either instead of Maybe
1589-- unconsEither :: Monad m => SerialT m a -> m (Either () (a, SerialT m a))
1604-- unconsEither :: Monad m => SerialT m a -> m (Either () (a, SerialT m a))
1590−-- unconsEither s = maybe (Left ()) Right <$> S.'uncons' s
1605+-- unconsEither s = maybe (Left ()) Right <$> Stream.'uncons' s
1591--
1606--
1592-- main = do
1607-- main = do
1593−-- S.'toList' (fromPipes (P.each [1..3])) >>= print
1608+-- Stream.'toList' (fromPipes (Pipe.each [1..3])) >>= print
1594−-- P.toListM (toPipes (S.'fromFoldable' [1..3])) >>= print
1609+-- Pipe.toListM (toPipes (Stream.'fromFoldable' [1..3])) >>= print
1595-- @
1610-- @
1596--
1611--
1597-- Interop with @streaming@:
1612-- Interop with @streaming@:
1598--
1613--
1599-- @
1614-- @
1600-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1615-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1601−-- import qualified "Streamly.Prelude" as S
1616+-- import qualified "Streamly.Prelude" as Stream
1602−-- import qualified Streaming as SG
1617+-- import qualified Streaming as Streaming
1603−-- import qualified Streaming.Prelude as SG
1618+-- import qualified Streaming.Prelude as Streaming
1604--
1619--
1605-- -- | streaming to streamly
1620-- -- | streaming to streamly
1606−-- fromStreaming :: (IsStream t, MonadAsync m) => SG.Stream (SG.Of a) m () -> t m a
1621+-- fromStreaming :: (IsStream t, MonadAsync m) => Streaming.Stream (Streaming.Of a) m () -> t m a
1607−-- fromStreaming = S.'unfoldrM' SG.uncons
1622+-- fromStreaming = Stream.'unfoldrM' Streaming.uncons
1608--
1623--
1609-- -- | streamly to streaming
1624-- -- | streamly to streaming
1610−-- toStreaming :: Monad m => SerialT m a -> SG.Stream (SG.Of a) m ()
1625+-- toStreaming :: Monad m => SerialT m a -> Streaming.Stream (Streaming.Of a) m ()
1611−-- toStreaming = SG.unfoldr unconsEither
1626+-- toStreaming = Streaming.unfoldr unconsEither
1612-- where
1627-- where
1613−-- -- Adapt S.uncons to return an Either instead of Maybe
1628+-- -- Adapt Stream.uncons to return an Either instead of Maybe
1614-- unconsEither :: Monad m => SerialT m a -> m (Either () (a, SerialT m a))
1629-- unconsEither :: Monad m => SerialT m a -> m (Either () (a, SerialT m a))
1615−-- unconsEither s = maybe (Left ()) Right <$> S.'uncons' s
1630+-- unconsEither s = maybe (Left ()) Right <$> Stream.'uncons' s
1616--
1631--
1617-- main = do
1632-- main = do
1618−-- S.'toList' (fromStreaming (SG.each [1..3])) >>= print
1633+-- Stream.'toList' (fromStreaming (Streaming.each [1..3])) >>= print
1619−-- SG.toList (toStreaming (S.'fromFoldable' [1..3])) >>= print
1634+-- Streaming.toList (toStreaming (Stream.'fromFoldable' [1..3])) >>= print
1620-- @
1635-- @
1621--
1636--
1622-- Interop with @conduit@:
1637-- Interop with @conduit@:
1623--
1638--
1624-- @
1639-- @
1625-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1640-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1626−-- import qualified "Streamly.Prelude" as S
1641+-- import qualified "Streamly.Prelude" as Stream
1627−-- import qualified Data.Conduit as C
1642+-- import qualified Data.Conduit as Conduit
1628−-- import qualified Data.Conduit.List as C
1643+-- import qualified Data.Conduit.List as Conduit
1629--
1644--
1630-- -- | conduit to streamly
1645-- -- | conduit to streamly
1631−-- fromConduit :: (IsStream t, MonadAsync m) => C.ConduitT () a m () -> t m a
1646+-- fromConduit :: (IsStream t, MonadAsync m) => Conduit.ConduitT () a m () -> t m a
1632−-- fromConduit = S.unfoldrM C.unconsM . C.sealConduitT
1647+-- fromConduit = Stream.unfoldrM Conduit.unconsM . Conduit.sealConduitT
1633--
1648--
1634-- -- | streamly to conduit
1649-- -- | streamly to conduit
1635−-- toConduit :: Monad m => SerialT m a -> C.ConduitT i a m ()
1650+-- toConduit :: Monad m => SerialT m a -> Conduit.ConduitT i a m ()
1636−-- toConduit = C.unfoldM S.'uncons'
1651+-- toConduit = Conduit.unfoldM Stream.'uncons'
1637--
1652--
1638-- main = do
1653-- main = do
1639−-- S.'toList' (fromConduit (C.sourceList [1..3])) >>= print
1654+-- Stream.'toList' (fromConduit (Conduit.sourceList [1..3])) >>= print
1640−-- C.runConduit (toConduit (S.'fromFoldable' [1..3]) C..| C.consume) >>= print
1655+-- Conduit.runConduit (toConduit (Stream.'fromFoldable' [1..3]) Conduit..| Conduit.consume) >>= print
1641-- @
1656-- @
1642
1657
1643-- $comparison
1658-- $comparison