on master help sign in
Fix Tutorial doctest
commitcbb57f25584d1a12a9f5577ddb499fa77671ff02 authorRanjeet Kumar Ranjan <ranjeetr@composewell.com> dateFri 4 Jun 2021, 19:48 (5 years ago) parent3feeec2
1 file changed+351−336
src/Streamly/Tutorial.hs+351−336
src/Streamly/Tutorial.hs+351−336
@@ -178,6 +178,31 @@ import Control.Monad
178178import Control.Monad.IO.Class (MonadIO(..))
179179import Control.Monad.Trans.Class (MonadTrans (lift))
180180
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+--
181206-- $streams
182207--
183208-- The monadic stream API offered by Streamly is very close to the Haskell
@@ -332,35 +357,29 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
332357-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
333358--
334359-- @
335−-- > S.'drain' $ liftIO $ putStrLn "Hello world!"
360+-- >>> Stream.drain $ liftIO $ putStrLn "Hello world!"
336361-- Hello world!
337−-- > S.'drain' $ lift $ putStrLn "Hello world!"
362+--
363+-- >>> Stream.drain $ lift $ putStrLn "Hello world!"
338364-- Hello world!
365+--
339366-- @
340367--
341368
342369-- $generating
343370--
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−--
354371-- 'nil' represents an empty stream and 'consM' or its operator form '|:' adds
355372-- a monadic action at the head of the stream.
356373--
357374-- @
358−-- > S.'toList' S.'nil'
375+-- >>> Stream.toList Stream.nil
359376-- []
360−-- > S.'toList' $ 'getLine' |: 'getLine' |: S.'nil'
377+--
378+-- Stream.toList $ getLine |: getLine |: Stream.nil
361379-- hello
362380-- world
363381-- ["hello","world"]
382+--
364383-- @
365384--
366385-- 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))
369388-- infinite stream.
370389--
371390-- @
372−-- > S.'toList' $ 'pure' 1
391+-- >>> Stream.toList $ pure 1
373392-- [1]
374−-- > S.'toList' $ S.'fromPure' 1
393+--
394+-- >>> Stream.toList $ Stream.fromPure 1
375395-- [1]
376−-- > S.'toList' $ S.'fromEffect' 'getLine'
396+--
397+-- Stream.toList $ Stream.fromEffect getLine
377398-- hello
378399-- ["hello"]
400+--
379401-- @
380402--
381403-- To create a stream from pure values in a 'Foldable' container use
382404-- 'fromFoldable' which is equivalent to a fold using 'cons' and 'nil':
383405--
384406-- @
385−-- > S.'toList' $ S.'fromFoldable' [1..3]
407+-- >>> Stream.toList $ Stream.fromFoldable [1..3]
386408-- [1,2,3]
387−-- > S.'toList' $ 'Prelude.foldr' S.'cons' S.'nil' [1..3]
409+--
410+-- >>> Stream.toList $ Prelude.foldr Stream.cons Stream.nil [1..3]
388411-- [1,2,3]
412+--
389413-- @
390414--
391415-- To create a stream from monadic actions in a 'Foldable' container just use a
392416-- right fold using 'consM' and 'nil':
393417--
394418-- @
395−-- > S.'drain' $ 'Prelude.foldr' ('|:') S.'nil' ['putStr' "Hello ", 'putStrLn' "world!"]
419+-- >>> Stream.drain $ Prelude.foldr (|:) Stream.nil [putStr "Hello ", putStrLn "world!"]
396420-- Hello world!
421+--
397422-- @
398423--
399424-- For more ways to construct a stream see the module "Streamly.Prelude".
@@ -410,26 +435,27 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
410435-- The following code finishes in 3 seconds (6 seconds when serial):
411436--
412437-- @
413−-- > let p n = threadDelay (n * 1000000) >> return n
414−-- > :set +s
415−-- > S.'toList' $ S.'fromParallel' $ p 3 |: p 2 |: p 1 |: S.'nil'
438+-- >>> let p n = threadDelay (n * 1000000) >> return n
439+-- >>> Stream.toList $ Stream.fromParallel $ p 3 |: p 2 |: p 1 |: Stream.nil
416440-- [1,2,3]
441+--
417442-- (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
419444-- [3,2,1]
445+--
420446-- (3.01 secs, 2,055,880 bytes)
421447-- @
422448-- The following finishes in 10 seconds (100 seconds when serial):
423449--
424450-- @
425−-- > S.'drain' $ S.'fromAsync' $ S.'replicateM' 10 $ p 10
451+-- Stream.'drain' $ Stream.'fromAsync' $ Stream.'replicateM' 10 $ p 10
426452-- (10.01 secs, 2,080,320 bytes)
427453-- @
428454--
429455
430456-- $eliminating
431457--
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
433459-- examples above. 'drain' runs a stream discarding the results i.e. only
434460-- for effects. 'toList' runs the stream and collects the results in a list.
435461--
@@ -450,8 +476,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
450476-- forever:
451477--
452478-- @
453−-- > import Data.Function ((&))
454−-- > S.'drain' $ S.'repeatM' getLine & S.'mapM' putStrLn
479+-- Stream.'drain' $ Stream.'repeatM' getLine & Stream.'mapM' putStrLn
455480-- @
456481--
457482-- The following code snippet reads lines from standard input, filters blank
@@ -459,18 +484,14 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
459484-- numbers them and prints them:
460485--
461486-- @
462−-- import qualified "Streamly.Prelude" as S
463−-- import Data.Char (toUpper)
464−-- import Data.Function ((&))
465−--
466−-- main = S.'drain' $
467−-- S.'repeatM' getLine
468−-- & S.'filter' (not . null)
469−-- & S.'drop' 1
470−-- & S.'take' 2
487+-- main = Stream.'drain' $
488+-- Stream.'repeatM' getLine
489+-- & Stream.'filter' (not . null)
490+-- & Stream.'drop' 1
491+-- & Stream.'take' 2
471492-- & fmap (map toUpper)
472−-- & S.'zipWith' (\\n s -> show n ++ " " ++ s) (S.'fromFoldable' [1..])
473−-- & S.'mapM' putStrLn
493+-- & Stream.'zipWith' (\\n s -> show n ++ " " ++ s) (Stream.'fromFoldable' [1..])
494+-- & Stream.'mapM' putStrLn
474495-- @
475496
476497-- $concurrentTransformation
@@ -483,8 +504,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
483504-- This would print a value every second (2 seconds when serial):
484505--
485506-- @
486−-- > 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))
507+-- let p n = threadDelay (n * 1000000) >> return n
508+-- Stream.'drain' $ Stream.'fromAhead' $ Stream.'mapM' (\\x -> p 1 >> print x) (Stream.'fromSerial' $ Stream.'repeatM' (p 1))
488509-- @
489510--
490511
@@ -498,8 +519,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
498519-- second instead of 2 seconds in the following:
499520--
500521-- @
501−-- > let p n = threadDelay (n * 1000000) >> return n
502−-- > S.'drain' $ S.'repeatM' (p 1) '|&' S.'mapM' (\\x -> p 1 >> print x)
522+-- let p n = threadDelay (n * 1000000) >> return n
523+-- Stream.'drain' $ Stream.'repeatM' (p 1) '|&' Stream.'mapM' (\\x -> p 1 >> print x)
503524-- @
504525
505526-- $semigroup
@@ -517,11 +538,20 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
517538-- not explicitly specified use the imports shown below.
518539--
519540-- @
520−-- import "Streamly.Prelude" ((|:), nil)
521−-- import qualified "Streamly.Prelude" as S
522−--
523−-- import Control.Concurrent
524−-- import Control.Monad (forever)
541+-- import Control.Concurrent
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
525555-- @
526556--
527557-- To illustrate concurrent vs serial composition aspects, we will use the
@@ -529,10 +559,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
529559-- seconds. After the delay it prints the number of seconds it slept.
530560--
531561-- @
532−-- delay n = S.'fromEffect' $ do
533−-- threadDelay (n * 1000000)
534−-- tid \<- myThreadId
535−-- putStrLn (show tid ++ ": Delay " ++ show n)
562+-- >>> :{
563+-- delay n = Stream.fromEffect $ do
564+-- threadDelay (n * 1000000)
565+-- tid <- myThreadId
566+-- putStrLn (show tid ++ ": Delay " ++ show n)
567+-- :}
568+--
536569-- @
537570
538571-- $serial
@@ -554,13 +587,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
554587-- 3, 4:
555588--
556589-- @
557−-- main = S.'drain' $ (print 1 |: print 2 |: S.nil) <> (print 3 |: print 4 |: S.nil)
558−-- @
559−-- @
590+-- >>> Stream.drain $ (print 1 |: print 2 |: Stream.nil) <> (print 3 |: print 4 |: Stream.nil)
560591-- 1
561592-- 2
562593-- 3
563594-- 4
595+--
564596-- @
565597--
566598-- All actions in both the streams are performed serially in the same thread.
@@ -568,12 +600,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
568600-- same thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
569601--
570602-- @
571−-- main = S.'drain' $ delay 3 <> delay 2 <> delay 1
572−-- @
573−-- @
574−-- ThreadId 36: Delay 3
575−-- ThreadId 36: Delay 2
576−-- ThreadId 36: Delay 1
603+-- >>> Stream.drain $ delay 3 <> delay 2 <> delay 1
604+-- ThreadId ... Delay 3
605+-- ThreadId ... Delay 2
606+-- ThreadId ... Delay 1
607+--
577608-- @
578609--
579610-- The polymorphic version of the binary operation '<>' of the 'Serial' type is
@@ -581,13 +612,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
581612-- irrespective of the type of stream:
582613--
583614-- @
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+--
585621-- @
586622
587623-- $interleaved
588624--
589625-- 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
591627-- combinator to effect 'WSerial' style of composition. We can also use the
592628-- 'WSerial' type annotation for the stream to achieve the same effect.
593629--
@@ -598,13 +634,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
598634-- The following example prints the sequence 1, 3, 2, 4
599635--
600636-- @
601−-- main = S.'drain' . S.'fromWSerial' $ (print 1 |: print 2 |: S.'nil') <> (print 3 |: print 4 |: S.'nil')
602−-- @
603−-- @
637+-- >>> Stream.drain . Stream.fromWSerial $ (print 1 |: print 2 |: Stream.nil) <> (print 3 |: print 4 |: Stream.nil)
604638-- 1
605639-- 3
606640-- 2
607641-- 4
642+--
608643-- @
609644--
610645-- Even though the monadic actions of the two streams are performed in an
@@ -613,27 +648,25 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
613648-- thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
614649--
615650-- @
616−-- main = S.'drain' . S.'fromWSerial' $ delay 3 <> delay 2 <> delay 1
617−-- @
618−-- @
619−-- ThreadId 36: Delay 3
620−-- ThreadId 36: Delay 2
621−-- ThreadId 36: Delay 1
651+-- >>> Stream.drain . Stream.fromWSerial $ delay 3 <> delay 2 <> delay 1
652+-- ThreadId ...: Delay 3
653+-- ThreadId ...: Delay 2
654+-- ThreadId ...: Delay 1
655+--
622656-- @
623657--
624658-- The polymorphic version of the 'WSerial' binary operation '<>' is called
625659-- '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
627661-- combinator in the following example:
628662--
629663-- @
630−-- main = S.'drain' $ (print 1 |: print 2 |: S.'nil') \`S.wSerial` (print 3 |: print 4 |: S.'nil')
631−-- @
632−-- @
664+-- >>> Stream.drain $ (print 1 |: print 2 |: Stream.nil) `Stream.wSerial` (print 3 |: print 4 |: Stream.nil)
633665-- 1
634666-- 3
635667-- 2
636668-- 4
669+--
637670-- @
638671--
639672-- Note that this composition cannot be used to fold infinite number of streams
@@ -656,13 +689,14 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
656689-- though each action in each stream takes one second:
657690--
658691-- @
659−-- main = do
660−-- xs \<- S.'toList' . S.'fromAhead' $ (p 1 |: p 2 |: S.nil) <> (p 3 |: p 4 |: S.nil)
661−-- print xs
662−-- where p n = threadDelay 1000000 >> return n
663−-- @
664−-- @
692+-- >>> p n = threadDelay 1000000 >> return n
693+-- >>> :{
694+-- do
695+-- xs <- Stream.toList . Stream.fromAhead $ (p 1 |: p 2 |: Stream.nil) <> (p 3 |: p 4 |: Stream.nil)
696+-- print xs
697+-- :}
665698-- [1,2,3,4]
699+--
666700-- @
667701--
668702-- Each stream is constructed 'aheadly' and then both the streams are merged
@@ -693,13 +727,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
693727-- The results are not guaranteed to be in any particular order:
694728--
695729-- @
696−-- main = do
697−-- xs \<- S.'toList' . S.'fromAsync' $ (p 1 |: p 2 |: S.'nil') <> (p 3 |: p 4 |: S.'nil')
730+-- p n = threadDelay 1000000 >> return n
731+-- do
732+-- xs <- Stream.toList . Stream.fromAsync $ (p 1 |: p 2 |: Stream.nil) <> (p 3 |: p 4 |: Stream.nil)
698733-- print xs
699−-- where p n = threadDelay 1000000 >> return n
700−-- @
701−-- @
702−-- [4,2,1,3]
734+--
735+-- [1,3,4,2]
703736-- @
704737--
705738-- The constituent streams are also composed in 'Async' manner and the
@@ -708,13 +741,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
708741-- The elements in the serial streams would be in serial order in the results:
709742--
710743-- @
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
715−-- @
716−-- @
717−-- [3,1,2,4]
744+-- > p n = threadDelay 1000000 >> return n
745+-- > Stream.toList . Stream.fromAsync $ (Stream.fromSerial $ p 1 |: p 2 |: Stream.nil) <> (fromSerial $ p 3 |: p 4 |: Stream.nil)
746+-- [1,3,4,2] -- order is not predictable
747+--
718748-- @
719749--
720750-- 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))
723753-- (3, 2, 1) = 3@ seconds:
724754--
725755-- @
726−-- main = S.'drain' . S.'fromAsync' $ delay 3 '<>' delay 2 '<>' delay 1
727−-- @
728−-- @
729−-- ThreadId 42: Delay 1
730−-- ThreadId 41: Delay 2
731−-- ThreadId 40: Delay 3
756+-- >>> Stream.drain . Stream.fromAsync $ delay 3 <> delay 2 <> delay 1
757+-- ThreadId ...: Delay 1
758+-- ThreadId ...: Delay 2
759+-- ThreadId ...: Delay 3
760+--
732761-- @
733762--
734763-- 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))
742771-- second as all of the actions are concurrent.
743772--
744773-- @
745−-- main = S.'drain' . S.'fromAsync' $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
746−-- @
747−-- @
748−-- 1
749−-- 2
750−-- 3
751−-- 4
774+-- >>> Stream.drain . Stream.fromAsync $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
775+-- ThreadId ...: Delay 1
776+-- ThreadId ...: Delay 2
777+-- ThreadId ...: Delay 3
778+-- ThreadId ...: Delay 4
779+--
752780-- @
753781--
754782-- 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))
759787-- even if none of them blocks:
760788--
761789-- @
762−-- main = S.'drain' . S.'fromAsync' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
763−-- where traced m = S.'fromEffect' (myThreadId >>= print) >> return m
790+-- main = Stream.'drain' . Stream.'fromAsync' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
791+-- where traced m = Stream.'fromEffect' (myThreadId >>= print) >> return m
764792-- @
765793-- @
766794-- ThreadId 40
@@ -777,12 +805,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
777805-- not used the 'fromAsync' combinator in the following example:
778806--
779807-- @
780−-- main = S.'drain' $ delay 3 \`S.'async'` delay 2 \`S.'async'` delay 1
781−-- @
782−-- @
783−-- ThreadId 42: Delay 1
784−-- ThreadId 41: Delay 2
785−-- ThreadId 40: Delay 3
808+-- >>> Stream.drain $ delay 3 `Stream.async` delay 2 `Stream.async` delay 1
809+-- ThreadId ...: Delay 1
810+-- ThreadId ...: Delay 2
811+-- ThreadId ...: Delay 3
812+--
786813-- @
787814--
788815-- Since the concurrency provided by this operator is demand driven it cannot
@@ -820,13 +847,16 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
820847-- first traversal order but this is not guaranteed.
821848--
822849-- @
823−-- main = S.'drain' . S.'fromWAsync' $ (S.'fromSerial' $ print 1 |: print 2 |: S.'nil') <> (S.'fromSerial' $ print 3 |: print 4 |: S.'nil')
824−-- @
825−-- @
850+-- >>> :{
851+-- do
852+-- hSetBuffering stdout LineBuffering
853+-- Stream.drain . Stream.fromWAsync $ (Stream.fromSerial $ print 1 |: print 2 |: Stream.nil) <> (Stream.fromSerial $ print 3 |: print 4 |: Stream.nil)
854+-- :}
826855-- 1
827856-- 3
828857-- 2
829858-- 4
859+--
830860-- @
831861--
832862-- The polymorphic version of the binary operation '<>' of the 'WAsync' type is
@@ -835,12 +865,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
835865-- the 'fromWAsync' combinator in the following example:
836866--
837867-- @
838−-- main = S.'drain' $ delay 3 \S.`wAsync` delay 2 \S.`wAsync` delay 1
839−-- @
840−-- @
841−-- ThreadId 42: Delay 1
842−-- ThreadId 41: Delay 2
843−-- ThreadId 40: Delay 3
868+-- >>> Stream.drain $ delay 3 `Stream.wAsync` delay 2 `Stream.wAsync` delay 1
869+-- ThreadId ...: Delay 1
870+-- ThreadId ...: Delay 2
871+-- ThreadId ...: Delay 3
872+--
844873-- @
845874--
846875-- Since the concurrency provided by this style is demand driven it may not
@@ -874,15 +903,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
874903-- package to run this example:
875904--
876905-- @
877−-- import qualified Streamly.Prelude as S
906+-- import qualified Streamly.Prelude as Stream
878907-- import Network.HTTP.Simple
879908--
880−-- main = S.'drain' . S.'fromParallel' $ google \<> bing \<> duckduckgo
909+-- main = Stream.'drain' . Stream.'fromParallel' $ google \<> bing \<> duckduckgo
881910-- where
882911-- google = get "https://www.google.com/search?q=haskell"
883912-- bing = get "https://www.bing.com/search?q=haskell"
884913-- 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))
886915-- @
887916--
888917-- The polymorphic version of the binary operation '<>' of the 'Parallel' type
@@ -891,12 +920,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
891920-- 'fromParallel' combinator in the following example:
892921--
893922-- @
894−-- main = S.'drain' $ delay 3 \`S.'parallel'` delay 2 \`S.'wAsync'` delay 1
895−-- @
896−-- @
897−-- ThreadId 42: Delay 1
898−-- ThreadId 41: Delay 2
899−-- ThreadId 40: Delay 3
923+-- >>> Stream.drain $ delay 3 `Stream.parallel` delay 2 `Stream.wAsync` delay 1
924+-- ThreadId ...: Delay 1
925+-- ThreadId ...: Delay 2
926+-- ThreadId ...: Delay 3
927+--
900928-- @
901929--
902930-- Note that this style of composition cannot be used to combine infinite
@@ -933,15 +961,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
933961-- second:
934962--
935963-- @
936−-- import qualified "Streamly.Prelude" as S
964+-- import qualified "Streamly.Prelude" as Stream
937965-- import Control.Concurrent
938966--
939967-- main = do
940−-- S.'drain' $ S.'fromAsync' $ foldMap delay [1..10]
941−-- S.'drain' $ S.'concatFoldableWith' S.'async' (map delay [1..10])
942−-- S.'drain' $ S.'concatMapFoldableWith' S.'async' delay [1..10]
943−-- S.'drain' $ S.'concatForFoldableWith' S.'async' [1..10] delay
944−-- where delay n = S.'fromEffect' $ threadDelay (n * 1000000) >> print n
968+-- Stream.'drain' $ Stream.'fromAsync' $ foldMap delay [1..10]
969+-- Stream.'drain' $ Stream.'concatFoldableWith' Stream.'async' (map delay [1..10])
970+-- Stream.'drain' $ Stream.'concatMapFoldableWith' Stream.'async' delay [1..10]
971+-- Stream.'drain' $ Stream.'concatForFoldableWith' Stream.'async' [1..10] delay
972+-- where delay n = Stream.'fromEffect' $ threadDelay (n * 1000000) >> print n
945973-- @
946974
947975-- $nesting
@@ -986,16 +1014,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
9861014-- instead.
9871015--
9881016-- @
989−-- import qualified "Streamly.Prelude" as S
990−--
991−-- main = S.'drain' $ do
992−-- x <- S.'fromFoldable' [3,2,1]
1017+-- >>> :{
1018+-- Stream.drain $ do
1019+-- x <- Stream.fromFoldable [3,2,1]
9931020-- delay x
994−-- @
995−-- @
996−-- ThreadId 30: Delay 3
997−-- ThreadId 30: Delay 2
998−-- ThreadId 30: Delay 1
1021+-- :}
1022+-- ThreadId ...: Delay 3
1023+-- ThreadId ...: Delay 2
1024+-- ThreadId ...: Delay 1
1025+--
9991026-- @
10001027--
10011028-- As we can see, the code after the @fromFoldable@ statement is run three
@@ -1007,11 +1034,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10071034-- written like this:
10081035--
10091036-- @
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
10151038-- @
10161039--
10171040-- When multiple streams are composed using this style they nest in a DFS
@@ -1020,18 +1043,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10201043-- loops in imperative programming.
10211044--
10221045-- @
1023−-- import qualified "Streamly.Prelude" as S
1024−--
1025−-- main = S.'drain' $ do
1026−-- x <- S.'fromFoldable' [1,2]
1027−-- y <- S.'fromFoldable' [3,4]
1028−-- S.'fromEffect' $ putStrLn $ show (x, y)
1029−-- @
1030−-- @
1046+-- >>> :{
1047+-- Stream.drain $ do
1048+-- x <- Stream.fromFoldable [1,2]
1049+-- y <- Stream.fromFoldable [3,4]
1050+-- Stream.fromEffect $ putStrLn $ show (x, y)
1051+-- :}
10311052-- (1,3)
10321053-- (1,4)
10331054-- (2,3)
10341055-- (2,4)
1056+--
10351057-- @
10361058--
10371059-- Notice that this is analogous to merging streams of type 'Serial' or merging
@@ -1048,19 +1070,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10481070-- type of the stream as 'Ahead'.
10491071--
10501072-- @
1051−-- import qualified "Streamly.Prelude" as S
1052−--
1053−-- comp = S.'toList' . S.'fromAhead' $ do
1054−-- x <- S.'fromFoldable' [3,2,1]
1055−-- delay x >> return x
1073+-- >>> :{
1074+-- comp = Stream.toList . Stream.fromAhead $ do
1075+-- x <- Stream.fromFoldable [3,2,1]
1076+-- delay x >> return x
1077+-- :}
10561078--
1057−-- main = comp >>= print
1058−-- @
1059−-- @
1060−-- ThreadId 40: Delay 1
1061−-- ThreadId 39: Delay 2
1062−-- ThreadId 38: Delay 3
1079+-- >>> comp >>= print
1080+-- ThreadId ...: Delay 1
1081+-- ThreadId ...: Delay 2
1082+-- ThreadId ...: Delay 3
10631083-- [3,2,1]
1084+--
10641085-- @
10651086--
10661087-- 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))
10881109-- type of the stream as 'Async'.
10891110--
10901111-- @
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
10921120--
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
11011121-- @
11021122--
11031123-- As we can see the code after the @fromFoldable@ statement is run three
@@ -1114,18 +1134,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11141134-- on the demand from the consumer of the stream.
11151135--
11161136-- @
1117−-- import qualified "Streamly.Prelude" as S
11181137--
1119−-- main = S.'drain' . S.'fromAsync' $ do
1120−-- x <- S.'fromFoldable' [1,2]
1121−-- y <- S.'fromFoldable' [3,4]
1122−-- S.'fromEffect' $ putStrLn $ show (x, y)
1123−-- @
1124−-- @
1138+-- Stream.drain . Stream.fromAsync $ do
1139+-- x <- Stream.fromFoldable [1,2]
1140+-- y <- Stream.fromFoldable [3,4]
1141+-- Stream.fromEffect $ putStrLn $ show (x, y)
1142+--
11251143-- (1,3)
11261144-- (1,4)
11271145-- (2,3)
11281146-- (2,4)
1147+--
11291148-- @
11301149
11311150-- $interleavedNesting
@@ -1133,23 +1152,22 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11331152-- The 'Monad' composition of 'WSerial' type interleaves the iterations of
11341153-- outer and inner loops in a nested loop composition. This works exactly the
11351154-- 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
11371156-- composition. Alternatively, a type annotation can be used to specify the
11381157-- type of the stream as 'WSerial'.
11391158--
11401159-- @
1141−-- import qualified "Streamly.Prelude" as S
1142−--
1143−-- main = S.'drain' . S.'fromWSerial' $ do
1144−-- x <- S.'fromFoldable' [1,2]
1145−-- y <- S.'fromFoldable' [3,4]
1146−-- S.fromEffect $ putStrLn $ show (x, y)
1147−-- @
1148−-- @
1160+-- >>> :{
1161+-- Stream.drain . Stream.fromWSerial $ do
1162+-- x <- Stream.fromFoldable [1,2]
1163+-- y <- Stream.fromFoldable [3,4]
1164+-- Stream.fromEffect $ putStrLn $ show (x, y)
1165+-- :}
11491166-- (1,3)
11501167-- (2,3)
11511168-- (1,4)
11521169-- (2,4)
1170+--
11531171-- @
11541172--
11551173
@@ -1165,18 +1183,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11651183-- specify the type of the stream as 'WAsync'.
11661184--
11671185-- @
1168−-- import qualified "Streamly.Prelude" as S
1169−--
1170−-- main = S.'drain' . S.'fromWAsync' $ do
1171−-- x <- S.'fromFoldable' [1,2]
1172−-- y <- S.'fromFoldable' [3,4]
1173−-- S.'fromEffect' $ putStrLn $ show (x, y)
1174−-- @
1175−-- @
1186+-- >>> :{
1187+-- Stream.drain . Stream.fromWAsync $ do
1188+-- x <- Stream.delay 1 $ Stream.fromFoldable [1,2]
1189+-- y <- Stream.delay 1 $ Stream.fromFoldable [3,4]
1190+-- Stream.fromEffect $ putStrLn $ show (x, y)
1191+-- :}
11761192-- (1,3)
1177−-- (2,3)
1178−-- (1,4)
1193+-- ...
1194+-- ...
11791195-- (2,4)
1196+--
11801197-- @
11811198
11821199-- $parallelNesting
@@ -1190,16 +1207,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11901207-- annotation can be used to specify the type of the stream as 'Parallel'.
11911208--
11921209-- @
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
11941218--
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
12031219-- @
12041220
12051221-- $monadExercise
@@ -1210,30 +1226,28 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
12101226-- specific mode of composition. For example take a look at the following code.
12111227--
12121228-- @
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 ()
12161230-- composed = do
12171231-- sz <- sizes
12181232-- cl <- colors
12191233-- sh <- shapes
1220−-- S.'fromEffect' $ putStrLn $ show (sz, cl, sh)
1234+-- Stream.'fromEffect' $ putStrLn $ show (sz, cl, sh)
12211235--
12221236-- where
12231237--
1224−-- sizes = S.'fromFoldable' [1, 2, 3]
1225−-- colors = S.'fromFoldable' ["red", "green", "blue"]
1226−-- shapes = S.'fromFoldable' ["triangle", "square", "circle"]
1238+-- sizes = Stream.'fromFoldable' [1, 2, 3]
1239+-- colors = Stream.'fromFoldable' ["red", "green", "blue"]
1240+-- shapes = Stream.'fromFoldable' ["triangle", "square", "circle"]
12271241-- @
12281242--
12291243-- Now we can interpret this in whatever way we want:
12301244--
12311245-- @
1232−-- main = S.'drain' . S.'fromSerial' $ composed
1233−-- main = S.'drain' . S.'fromWSerial' $ composed
1234−-- main = S.'drain' . S.'fromAsync' $ composed
1235−-- main = S.'drain' . S.'fromWAsync' $ composed
1236−-- main = S.'drain' . S.'fromParallel' $ composed
1246+-- main = Stream.'drain' . Stream.'fromSerial' $ composed
1247+-- main = Stream.'drain' . Stream.'fromWSerial' $ composed
1248+-- main = Stream.'drain' . Stream.'fromAsync' $ composed
1249+-- main = Stream.'drain' . Stream.'fromWAsync' $ composed
1250+-- main = Stream.'drain' . Stream.'fromParallel' $ composed
12371251-- @
12381252--
12391253-- 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))
12461260-- serial.
12471261--
12481262-- @
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"]
12501265--
1251−-- main = (S.'toList' $ fmap show $ S.'fromFoldable' [1..10]) >>= print
12521266-- @
12531267--
12541268-- Also see functions 'mapM' and 'sequence' from "Streamly.Prelude" module
@@ -1264,46 +1278,41 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
12641278-- serially and takes a total 17 seconds (1 + 3 + 4 + 2 + 3 + 4):
12651279--
12661280-- @
1267−-- import qualified "Streamly.Prelude" as S
1268−-- import Control.Concurrent
1281+-- >>> d n = delay n >> return n
1282+-- >>> s1 = d 1 <> d 2
1283+-- >>> s2 = d 3 <> d 4
12691284--
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
1275−-- @
1276−-- @
1277−-- ThreadId 36: Delay 1
1278−-- ThreadId 36: Delay 3
1279−-- ThreadId 36: Delay 4
1280−-- ThreadId 36: Delay 2
1281−-- ThreadId 36: Delay 3
1282−-- ThreadId 36: Delay 4
1285+-- >>> (Stream.toList . Stream.fromSerial $ (,) <$> s1 <*> s2) >>= print
1286+-- ThreadId ...: Delay 1
1287+-- ThreadId ...: Delay 3
1288+-- ThreadId ...: Delay 4
1289+-- ThreadId ...: Delay 2
1290+-- ThreadId ...: Delay 3
1291+-- ThreadId ...: Delay 4
12831292-- [(1,3),(1,4),(2,3),(2,4)]
1293+--
12841294-- @
12851295--
12861296-- Similarly 'WSerial' applicative runs the iterations in an interleaved
12871297-- order but since it is serial it takes a total of 17 seconds:
12881298--
12891299-- @
1290−-- main = (S.'toList' . S.'fromWSerial' $ (,) \<$> s1 \<*> s2) >>= print
1291−-- @
1292−-- @
1293−-- ThreadId 36: Delay 1
1294−-- ThreadId 36: Delay 3
1295−-- ThreadId 36: Delay 2
1296−-- ThreadId 36: Delay 3
1297−-- ThreadId 36: Delay 4
1298−-- ThreadId 36: Delay 4
1300+-- >>> (Stream.toList . Stream.fromWSerial $ (,) <$> s1 <*> s2) >>= print
1301+-- ThreadId ...: Delay 1
1302+-- ThreadId ...: Delay 3
1303+-- ThreadId ...: Delay 2
1304+-- ThreadId ...: Delay 3
1305+-- ThreadId ...: Delay 4
1306+-- ThreadId ...: Delay 4
12991307-- [(1,3),(2,3),(1,4),(2,4)]
1308+--
13001309-- @
13011310--
13021311-- 'Async' can run the iterations concurrently and therefore takes a total
13031312-- of 6 seconds which is max (1, 2) + max (3, 4):
13041313--
13051314-- @
1306−-- main = (S.'toList' . S.'fromAsync' $ (,) \<$> s1 \<*> s2) >>= print
1315+-- main = (Stream.'toList' . Stream.'fromAsync' $ (,) \<$> s1 \<*> s2) >>= print
13071316-- @
13081317-- @
13091318-- ThreadId 34: Delay 1
@@ -1319,7 +1328,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
13191328-- therefore takes a total of 6 seconds (2 + 4):
13201329--
13211330-- @
1322−-- main = (S.'toList' . S.'fromWAsync' $ (,) \<$> s1 \<*> s2) >>= print
1331+-- main = (Stream.'toList' . Stream.'fromWAsync' $ (,) \<$> s1 \<*> s2) >>= print
13231332-- @
13241333-- @
13251334-- ThreadId 34: Delay 1
@@ -1347,26 +1356,27 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
13471356-- zip composition:
13481357--
13491358-- @
1350−-- import qualified "Streamly.Prelude" as S
1351−-- import Control.Concurrent
13521359--
13531360-- d n = delay n >> return n
1354−-- s1 = S.'fromSerial' $ d 1 <> d 2
1355−-- s2 = S.'fromSerial' $ d 3 <> d 4
1361+-- s1 = Stream.'fromSerial' $ d 1 <> d 2
1362+-- s2 = Stream.'fromSerial' $ d 3 <> d 4
13561363--
1357−-- main = (S.'toList' . S.'fromZipSerial' $ (,) \<$> s1 \<*> s2) >>= print
1364+-- main = (Stream.'toList' . Stream.'fromZipSerial' $ (,) \<$> s1 \<*> s2) >>= print
13581365-- @
13591366--
13601367-- This takes total 10 seconds to zip, which is (1 + 2 + 3 + 4) since
13611368-- everything runs serially:
13621369--
1363−-- @
1364−-- ThreadId 29: Delay 1
1365−-- ThreadId 29: Delay 3
1366−-- ThreadId 29: Delay 2
1367−-- ThreadId 29: Delay 4
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
1374+-- ThreadId ...: Delay 1
1375+-- ThreadId ...: Delay 3
1376+-- ThreadId ...: Delay 2
1377+-- ThreadId ...: Delay 4
13681378-- [(1,3),(2,4)]
1369−-- @
1379+--
13701380
13711381-- $parallelzip
13721382--
@@ -1376,29 +1386,35 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
13761386--
13771387--
13781388-- @
1379−-- import qualified "Streamly.Prelude" as S
1380−-- import Control.Concurrent
13811389-- import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
13821390--
13831391-- d n = delay n >> return n
1384−-- s1 = S.'fromSerial' $ d 1 <> d 2
1385−-- s2 = S.'fromSerial' $ d 3 <> d 4
1392+-- s1 = Stream.'fromSerial' $ d 1 <> d 2
1393+-- s2 = Stream.'fromSerial' $ d 3 <> d 4
13861394--
13871395-- main = do
13881396-- hSetBuffering stdout LineBuffering
1389−-- (S.'toList' . S.'fromZipAsync' $ (,) \<$> s1 \<*> s2) >>= print
1397+-- (Stream.'toList' . Stream.'fromZipAsync' $ (,) \<$> s1 \<*> s2) >>= print
13901398-- @
13911399--
13921400-- This takes 7 seconds to zip, which is max (1,3) + max (2,4) because 1 and 3
13931401-- are produced concurrently, and 2 and 4 are produced concurrently:
13941402--
1395−-- @
1396−-- ThreadId 32: Delay 1
1397−-- ThreadId 32: Delay 2
1398−-- ThreadId 33: Delay 3
1399−-- ThreadId 33: Delay 4
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+-- :}
1412+-- ThreadId ...: Delay 1
1413+-- ThreadId ...: Delay 2
1414+-- ThreadId ...: Delay 3
1415+-- ThreadId ...: Delay 4
14001416-- [(1,3),(2,4)]
1401−-- @
1417+--
14021418
14031419-- $concurrent
14041420--
@@ -1417,16 +1433,16 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
14171433-- combinator instead of explicitly folding with 'async'.
14181434--
14191435-- @
1420−-- import qualified "Streamly.Prelude" as S
1436+-- import qualified "Streamly.Prelude" as Stream
14211437-- import Data.List (sum)
14221438--
14231439-- main = do
1424−-- z \<- S.'toList'
1425−-- $ S.'fromSerial' -- Serial monadic processing (sqrt below)
1440+-- z \<- Stream.'toList'
1441+-- $ Stream.'fromSerial' -- Serial monadic processing (sqrt below)
14261442-- $ do
1427−-- x2 \<- S.'concatForFoldableWith' S.'async' [1..100] $ -- Concurrent @"for"@ loop
1443+-- x2 \<- Stream.'concatForFoldableWith' Stream.'async' [1..100] $ -- Concurrent @"for"@ loop
14281444-- \\x -> return $ x * x -- body of the loop
1429−-- y2 \<- S.'concatForFoldableWith' S.'async' [1..100] $
1445+-- y2 \<- Stream.'concatForFoldableWith' Stream.'async' [1..100] $
14301446-- \\y -> return $ y * y
14311447-- return $ sqrt (x2 + y2)
14321448-- print $ sum z
@@ -1459,10 +1475,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
14591475-- health improves and the game continues.
14601476--
14611477-- @
1462−-- {-\# LANGUAGE FlexibleContexts #-}
1478+-- {-\# LANGUAGE FlexibleContexts \#-}
14631479--
14641480-- import "Streamly.Prelude" (MonadAsync, SerialT)
1465−-- import "Streamly.Prelude" as S
1481+-- import "Streamly.Prelude" as Stream
14661482-- import Control.Monad (void)
14671483-- import Control.Monad.IO.Class (MonadIO(liftIO))
14681484-- import Control.Monad.State (MonadState, get, modify, runStateT)
@@ -1470,7 +1486,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
14701486-- data Event = Quit | Harm Int | Heal Int deriving (Show)
14711487--
14721488-- userAction :: MonadAsync m => 'SerialT' m Event
1473−-- userAction = S.'repeatM' $ liftIO askUser
1489+-- userAction = Stream.'repeatM' $ liftIO askUser
14741490-- where
14751491-- askUser = do
14761492-- command <- getLine
@@ -1481,13 +1497,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
14811497-- _ -> putStrLn "Type potion or harm or quit" >> askUser
14821498--
14831499-- 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
14851501--
14861502-- data Result = Check | Done
14871503--
14881504-- runEvents :: (MonadAsync m, MonadState Int m) => 'SerialT' m Result
14891505-- runEvents = do
1490−-- event \<- userAction \`S.'parallel'` acidRain
1506+-- event \<- userAction \`Stream.'parallel'` acidRain
14911507-- case event of
14921508-- Harm n -> modify (\\h -> h - n) >> return Check
14931509-- Heal n -> modify (\\h -> h + n) >> return Check
@@ -1507,9 +1523,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
15071523--
15081524-- main :: IO ()
15091525-- main = do
1510−-- putStrLn "Your health is deteriorating due to acid rain,\\
1511−-- \\ type \\"potion\\" or \\"quit\\""
1512−-- let runGame = S.'drainWhile' (== Alive) $ S.'mapM' getStatus runEvents
1526+-- putStrLn "Your health is deteriorating due to acid rain, type \\\"potion\\\" or \\\"quit\\\""
1527+-- let runGame = Stream.'drainWhile' (== Alive) $ Stream.'mapM' getStatus runEvents
15131528-- void $ runStateT runGame 60
15141529-- @
15151530--
@@ -1542,102 +1557,102 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
15421557--
15431558-- @
15441559-- import "Streamly.Prelude" (SerialT)
1545−-- import qualified "Streamly.Prelude" as S
1546−-- import qualified Data.Vector.Fusion.Stream.Monadic as V
1560+-- import qualified "Streamly.Prelude" as Stream
1561+-- import qualified Data.Vector.Fusion.Stream.Monadic as Vector
15471562--
15481563-- -- | vector to streamly
1549−-- fromVector :: (S.IsStream t, Monad m) => V.Stream m a -> t m a
1550−-- fromVector = S.unfoldrM unconsV
1564+-- fromVector :: (Stream.IsStream t, Monad m) => Vector.Stream m a -> t m a
1565+-- fromVector = Stream.unfoldrM unconsV
15511566-- where
15521567-- unconsV v = do
1553−-- r <- V.null v
1568+-- r <- Vector.null v
15541569-- if r
15551570-- then return Nothing
15561571-- else do
1557−-- h <- V.head v
1558−-- return $ Just (h, V.tail v)
1572+-- h <- Vector.head v
1573+-- return $ Just (h, Vector.tail v)
15591574--
15601575-- -- | streamly to vector
1561−-- toVector :: Monad m => SerialT m a -> V.Stream m a
1562−-- toVector = V.unfoldrM (S.uncons . S.adapt)
1576+-- toVector :: Monad m => SerialT m a -> Vector.Stream m a
1577+-- toVector = Vector.unfoldrM (Stream.uncons . Stream.adapt)
15631578--
15641579-- main = do
1565−-- S.toList (fromVector (V.fromList [1..3])) >>= print
1566−-- V.toList (toVector (S.fromFoldable [1..3])) >>= print
1580+-- Stream.toList (fromVector (Vector.fromList [1..3])) >>= print
1581+-- Vector.toList (toVector (Stream.fromFoldable [1..3])) >>= print
15671582-- @
15681583--
15691584-- Interop with @pipes@:
15701585--
15711586-- @
15721587-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1573−-- import qualified "Streamly.Prelude" as S
1574−-- import qualified Pipes as P
1575−-- import qualified Pipes.Prelude as P
1588+-- import qualified "Streamly.Prelude" as Stream
1589+-- import qualified Pipes as Pipe
1590+-- import qualified Pipes.Prelude as Pipe
15761591--
15771592-- -- | pipes to streamly
1578−-- fromPipes :: (IsStream t, MonadAsync m) => P.Producer a m () -> t m a
1579−-- fromPipes = S.'unfoldrM' unconsP
1593+-- fromPipes :: (IsStream t, MonadAsync m) => Pipe.Producer a m () -> t m a
1594+-- fromPipes = Stream.'unfoldrM' unconsP
15801595-- where
1581−-- -- Adapt P.next to return a Maybe instead of Either
1582−-- unconsP p = either (const Nothing) Just <$> P.next p
1596+-- -- Adapt Pipe.next to return a Maybe instead of Either
1597+-- unconsP p = either (const Nothing) Just <$> Pipe.next p
15831598--
15841599-- -- | streamly to pipes
1585−-- toPipes :: Monad m => SerialT m a -> P.Producer a m ()
1586−-- toPipes = P.unfoldr unconsEither
1600+-- toPipes :: Monad m => SerialT m a -> Pipe.Producer a m ()
1601+-- toPipes = Pipe.unfoldr unconsEither
15871602-- where
1588−-- -- Adapt S.uncons to return an Either instead of Maybe
1603+-- -- Adapt Stream.uncons to return an Either instead of Maybe
15891604-- 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
15911606--
15921607-- main = do
1593−-- S.'toList' (fromPipes (P.each [1..3])) >>= print
1594−-- P.toListM (toPipes (S.'fromFoldable' [1..3])) >>= print
1608+-- Stream.'toList' (fromPipes (Pipe.each [1..3])) >>= print
1609+-- Pipe.toListM (toPipes (Stream.'fromFoldable' [1..3])) >>= print
15951610-- @
15961611--
15971612-- Interop with @streaming@:
15981613--
15991614-- @
16001615-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1601−-- import qualified "Streamly.Prelude" as S
1602−-- import qualified Streaming as SG
1603−-- import qualified Streaming.Prelude as SG
1616+-- import qualified "Streamly.Prelude" as Stream
1617+-- import qualified Streaming as Streaming
1618+-- import qualified Streaming.Prelude as Streaming
16041619--
16051620-- -- | streaming to streamly
1606−-- fromStreaming :: (IsStream t, MonadAsync m) => SG.Stream (SG.Of a) m () -> t m a
1607−-- fromStreaming = S.'unfoldrM' SG.uncons
1621+-- fromStreaming :: (IsStream t, MonadAsync m) => Streaming.Stream (Streaming.Of a) m () -> t m a
1622+-- fromStreaming = Stream.'unfoldrM' Streaming.uncons
16081623--
16091624-- -- | streamly to streaming
1610−-- toStreaming :: Monad m => SerialT m a -> SG.Stream (SG.Of a) m ()
1611−-- toStreaming = SG.unfoldr unconsEither
1625+-- toStreaming :: Monad m => SerialT m a -> Streaming.Stream (Streaming.Of a) m ()
1626+-- toStreaming = Streaming.unfoldr unconsEither
16121627-- where
1613−-- -- Adapt S.uncons to return an Either instead of Maybe
1628+-- -- Adapt Stream.uncons to return an Either instead of Maybe
16141629-- 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
16161631--
16171632-- main = do
1618−-- S.'toList' (fromStreaming (SG.each [1..3])) >>= print
1619−-- SG.toList (toStreaming (S.'fromFoldable' [1..3])) >>= print
1633+-- Stream.'toList' (fromStreaming (Streaming.each [1..3])) >>= print
1634+-- Streaming.toList (toStreaming (Stream.'fromFoldable' [1..3])) >>= print
16201635-- @
16211636--
16221637-- Interop with @conduit@:
16231638--
16241639-- @
16251640-- import "Streamly.Prelude" (IsStream, MonadAsync, SerialT)
1626−-- import qualified "Streamly.Prelude" as S
1627−-- import qualified Data.Conduit as C
1628−-- import qualified Data.Conduit.List as C
1641+-- import qualified "Streamly.Prelude" as Stream
1642+-- import qualified Data.Conduit as Conduit
1643+-- import qualified Data.Conduit.List as Conduit
16291644--
16301645-- -- | conduit to streamly
1631−-- fromConduit :: (IsStream t, MonadAsync m) => C.ConduitT () a m () -> t m a
1632−-- fromConduit = S.unfoldrM C.unconsM . C.sealConduitT
1646+-- fromConduit :: (IsStream t, MonadAsync m) => Conduit.ConduitT () a m () -> t m a
1647+-- fromConduit = Stream.unfoldrM Conduit.unconsM . Conduit.sealConduitT
16331648--
16341649-- -- | streamly to conduit
1635−-- toConduit :: Monad m => SerialT m a -> C.ConduitT i a m ()
1636−-- toConduit = C.unfoldM S.'uncons'
1650+-- toConduit :: Monad m => SerialT m a -> Conduit.ConduitT i a m ()
1651+-- toConduit = Conduit.unfoldM Stream.'uncons'
16371652--
16381653-- main = do
1639−-- S.'toList' (fromConduit (C.sourceList [1..3])) >>= print
1640−-- C.runConduit (toConduit (S.'fromFoldable' [1..3]) C..| C.consume) >>= print
1654+-- Stream.'toList' (fromConduit (Conduit.sourceList [1..3])) >>= print
1655+-- Conduit.runConduit (toConduit (Stream.'fromFoldable' [1..3]) Conduit..| Conduit.consume) >>= print
16411656-- @
16421657
16431658-- $comparison