@@ -170,7 +170,7 @@ module Streamly.Tutorial
173−import Streamly
173+import Streamly hiding (foldWith, foldMapWith, forEachWith)
174import Streamly.Prelude
174import Streamly.Prelude
175import Data.Semigroup
175import Data.Semigroup
176import Control.Applicative
176import Control.Applicative
@@ -332,9 +332,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
332-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
332-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
335−-- > 'drain' $ liftIO $ putStrLn "Hello world!"
335+-- > S.'drain' $ liftIO $ putStrLn "Hello world!"
336-- Hello world!
336-- Hello world!
337−-- > 'drain' $ lift $ putStrLn "Hello world!"
337+-- > S.'drain' $ lift $ putStrLn "Hello world!"
338-- Hello world!
338-- Hello world!
@@ -348,6 +348,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
348-- > import "Streamly"
348-- > import "Streamly"
349-- > import "Streamly.Prelude" ((|:))
349-- > import "Streamly.Prelude" ((|:))
350-- > import qualified "Streamly.Prelude" as S
350-- > import qualified "Streamly.Prelude" as S
352+-- > import Control.Concurrent
353-- 'nil' represents an empty stream and 'consM' or its operator form '|:' adds
355-- 'nil' represents an empty stream and 'consM' or its operator form '|:' adds
@@ -370,7 +372,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
371-- > S.'toList' $ 'pure' 1
373-- > S.'toList' $ 'pure' 1
373−-- > S.'toList' $ 'yield' 1
375+-- > S.'toList' $ S.'yield' 1
375-- > S.'toList' $ S.'yieldM' 'getLine'
377-- > S.'toList' $ S.'yieldM' 'getLine'
@@ -391,7 +393,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
391-- right fold using 'consM' and 'nil':
393-- right fold using 'consM' and 'nil':
394−-- > 'drain' $ 'Prelude.foldr' ('|:') S.'nil' ['putStr' "Hello ", 'putStrLn' "world!"]
396+-- > S.'drain' $ 'Prelude.foldr' ('|:') S.'nil' ['putStr' "Hello ", 'putStrLn' "world!"]
395-- Hello world!
397-- Hello world!
@@ -418,7 +420,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
418-- The following finishes in 10 seconds (100 seconds when serial):
420-- The following finishes in 10 seconds (100 seconds when serial):
421−-- > 'drain' $ 'asyncly' $ S.'replicateM' 10 $ p 10
423+-- > S.drain $ 'asyncly' $ S.'replicateM' 10 $ p 10
@@ -445,7 +447,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
445-- forever:
447-- forever:
450+-- > import Data.Function ((&))
448−-- > 'drain' $ S.'repeatM' getLine & S.'mapM' putStrLn
451+-- > S.'drain' $ S.'repeatM' getLine & S.'mapM' putStrLn
451-- The following code snippet reads lines from standard input, filters blank
454-- The following code snippet reads lines from standard input, filters blank
@@ -458,7 +461,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
458-- import Data.Char (toUpper)
461-- import Data.Char (toUpper)
459-- import Data.Function ((&))
462-- import Data.Function ((&))
461−-- main = 'drain' $
464+-- main = S.'drain' $
462-- S.'repeatM' getLine
465-- S.'repeatM' getLine
463-- & S.'filter' (not . null)
466-- & S.'filter' (not . null)
464-- & S.'drop' 1
467-- & S.'drop' 1
@@ -479,7 +482,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
481-- > let p n = threadDelay (n * 1000000) >> return n
484-- > let p n = threadDelay (n * 1000000) >> return n
482−-- > drain $ aheadly $ S.'mapM' (\\x -> p 1 >> print x) (serially $ repeatM (p 1))
485+-- > S.'drain' $ S.aheadly $ S.'mapM' (\\x -> p 1 >> print x) (serially $ S.repeatM (p 1))
@@ -494,7 +497,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
496-- > let p n = threadDelay (n * 1000000) >> return n
499-- > let p n = threadDelay (n * 1000000) >> return n
497−-- > drain $ S.'repeatM' (p 1) '|&' S.'mapM' (\\x -> p 1 >> print x)
500+-- > S.'drain' $ S.'repeatM' (p 1) '|&' S.'mapM' (\\x -> p 1 >> print x)
500-- $semigroup
503-- $semigroup
@@ -550,7 +553,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
553−-- main = 'drain' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
556+-- main = S.'drain' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
@@ -564,7 +567,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
564-- same thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
567-- same thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
567−-- main = 'drain' $ delay 3 <> delay 2 <> delay 1
570+-- main = S.'drain' $ delay 3 <> delay 2 <> delay 1
570-- ThreadId 36: Delay 3
573-- ThreadId 36: Delay 3
@@ -577,7 +580,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
577-- irrespective of the type of stream:
580-- irrespective of the type of stream:
580−-- main = 'drain' $ (print 1 |: print 2 |: nil) \`serial` (print 3 |: print 4 |: nil)
583+-- main = S.'drain' $ (print 1 |: print 2 |: nil) \`serial` (print 3 |: print 4 |: nil)
583-- $interleaved
586-- $interleaved
@@ -594,7 +597,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
594-- The following example prints the sequence 1, 3, 2, 4
597-- The following example prints the sequence 1, 3, 2, 4
597−-- main = 'drain' . 'wSerially' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
600+-- main = S.'drain' . 'wSerially' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
@@ -609,7 +612,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
609-- thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
612-- thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
612−-- main = 'drain' . 'wSerially' $ delay 3 <> delay 2 <> delay 1
615+-- main = S.'drain' . 'wSerially' $ delay 3 <> delay 2 <> delay 1
615-- ThreadId 36: Delay 3
618-- ThreadId 36: Delay 3
@@ -623,7 +626,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
623-- combinator in the following example:
626-- combinator in the following example:
626−-- main = 'drain' $ (print 1 |: print 2 |: nil) \`wSerial` (print 3 |: print 4 |: nil)
629+-- main = S.'drain' $ (print 1 |: print 2 |: nil) \`wSerial` (print 3 |: print 4 |: nil)
@@ -653,7 +656,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
655-- main = do
658-- main = do
656−-- xs \<- 'toList' . 'aheadly' $ (p 1 |: p 2 |: nil) <> (p 3 |: p 4 |: nil)
659+-- xs \<- S.'toList' . 'aheadly' $ (p 1 |: p 2 |: nil) <> (p 3 |: p 4 |: nil)
657-- print xs
660-- print xs
658-- where p n = threadDelay 1000000 >> return n
661-- where p n = threadDelay 1000000 >> return n
@@ -690,7 +693,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
692-- main = do
695-- main = do
693−-- xs \<- 'drain' . 'asyncly' $ (p 1 |: p 2 |: nil) <> (p 3 |: p 4 |: nil)
696+-- xs \<- S.'toList' . 'asyncly' $ (p 1 |: p 2 |: nil) <> (p 3 |: p 4 |: nil)
694-- print xs
697-- print xs
695-- where p n = threadDelay 1000000 >> return n
698-- where p n = threadDelay 1000000 >> return n
@@ -705,7 +708,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
707-- main = do
710-- main = do
708−-- xs \<- 'drain' . 'asyncly' $ (serially $ p 1 |: p 2 |: nil) <> (serially $ p 3 |: p 4 |: nil)
711+-- xs \<- S.'toList' . 'asyncly' $ (serially $ p 1 |: p 2 |: nil) <> (serially $ p 3 |: p 4 |: nil)
709-- print xs
712-- print xs
710-- where p n = threadDelay 1000000 >> return n
713-- where p n = threadDelay 1000000 >> return n
@@ -719,7 +722,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
719-- (3, 2, 1) = 3@ seconds:
722-- (3, 2, 1) = 3@ seconds:
722−-- main = 'drain' . 'asyncly' $ delay 3 '<>' delay 2 '<>' delay 1
725+-- main = S.'drain' . 'asyncly' $ delay 3 '<>' delay 2 '<>' delay 1
725-- ThreadId 42: Delay 1
728-- ThreadId 42: Delay 1
@@ -738,7 +741,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
738-- second as all of the actions are concurrent.
741-- second as all of the actions are concurrent.
741−-- main = 'drain' . 'asyncly' $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
744+-- main = S.'drain' . 'asyncly' $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
@@ -755,7 +758,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
755-- even if none of them blocks:
758-- even if none of them blocks:
758−-- main = 'drain' . 'asyncly' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
761+-- main = S.'drain' . 'asyncly' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
759-- where traced m = S.'yieldM' (myThreadId >>= print) >> return m
762-- where traced m = S.'yieldM' (myThreadId >>= print) >> return m
@@ -773,7 +776,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
773-- not used the 'asyncly' combinator in the following example:
776-- not used the 'asyncly' combinator in the following example:
776−-- main = 'drain' $ delay 3 \`async` delay 2 \`async` delay 1
779+-- main = S.'drain' $ delay 3 \`async` delay 2 \`async` delay 1
779-- ThreadId 42: Delay 1
782-- ThreadId 42: Delay 1
@@ -789,11 +792,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
789-- all computations at once for any reason 'Parallel' style must be used
792-- all computations at once for any reason 'Parallel' style must be used
790-- instead.
793-- instead.
792−-- 'Async' style should be preferred over 'Parallel' or 'WAsync' unless you
795+-- 'Async' style utilizes resources optimally and should be preferred over
793−-- really need those. It utilizes the resources optimally. It should be used
796+-- 'Parallel' or 'WAsync' unless you really need those. 'Async' should be used
794-- when we know that the computations can run in parallel but we do not care if
797-- when we know that the computations can run in parallel but we do not care if
795-- they actually run in parallel or not, that decision can be left to the
798-- they actually run in parallel or not, that decision can be left to the
796−-- scheduler based on demand. Also, note that this operator can be used to fold
799+-- scheduler based on demand. Also, note that 'async' operator can be used to fold
797-- infinite number of streams in contrast to the 'Parallel' or 'WAsync' styles,
800-- infinite number of streams in contrast to the 'Parallel' or 'WAsync' styles,
798-- because it does not require us to run all of them at the same time in a fair
801-- because it does not require us to run all of them at the same time in a fair
799-- manner.
802-- manner.
@@ -816,7 +819,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
816-- first traversal order but this is not guaranteed.
819-- first traversal order but this is not guaranteed.
819−-- main = 'drain' . 'wAsyncly' $ (serially $ print 1 |: print 2 |: nil) <> (serially $ print 3 |: print 4 |: nil)
822+-- main = S.'drain' . 'wAsyncly' $ (serially $ print 1 |: print 2 |: nil) <> (serially $ print 3 |: print 4 |: nil)
@@ -831,7 +834,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
831-- the 'wAsyncly' combinator in the following example:
834-- the 'wAsyncly' combinator in the following example:
834−-- main = 'drain' $ delay 3 \`wAsync` delay 2 \`wAsync` delay 1
837+-- main = S.'drain' $ delay 3 \`wAsync` delay 2 \`wAsync` delay 1
837-- ThreadId 42: Delay 1
840-- ThreadId 42: Delay 1
@@ -866,14 +869,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
867-- The following example sends a query to all the three search engines in
870-- The following example sends a query to all the three search engines in
868-- parallel and prints the name of the search engines in the order in which the
871-- parallel and prints the name of the search engines in the order in which the
869−-- responses arrive:
872+-- responses arrive. You need the [http-conduit](http://hackage.haskell.org/package/http-conduit)
873+-- package to run this example:
872-- import "Streamly"
876-- import "Streamly"
873-- import qualified Streamly.Prelude as S
877-- import qualified Streamly.Prelude as S
874-- import Network.HTTP.Simple
878-- import Network.HTTP.Simple
876−-- main = 'drain' . 'parallely' $ google \<> bing \<> duckduckgo
880+-- main = S.'drain' . 'parallely' $ google \<> bing \<> duckduckgo
878-- google = get "https://www.google.com/search?q=haskell"
882-- google = get "https://www.google.com/search?q=haskell"
879-- bing = get "https://www.bing.com/search?q=haskell"
883-- bing = get "https://www.bing.com/search?q=haskell"
@@ -887,7 +891,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
887-- 'parallely' combinator in the following example:
891-- 'parallely' combinator in the following example:
890−-- main = 'drain' $ delay 3 \`parallel` delay 2 \`wAsync` delay 1
894+-- main = S.'drain' $ delay 3 \`parallel` delay 2 \`wAsync` delay 1
893-- ThreadId 42: Delay 1
897-- ThreadId 42: Delay 1
@@ -934,10 +938,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
934-- import Control.Concurrent
938-- import Control.Concurrent
936-- main = do
940-- main = do
937−-- 'drain' $ 'asyncly' $ foldMap delay [1..10]
941+-- S.'drain' $ 'asyncly' $ foldMap delay [1..10]
938−-- 'drain' $ 'foldWith' 'async' (map delay [1..10])
942+-- S.'drain' $ S.'foldWith' 'async' (map delay [1..10])
939−-- 'drain' $ 'foldMapWith' 'async' delay [1..10]
943+-- S.'drain' $ S.'foldMapWith' 'async' delay [1..10]
940−-- 'drain' $ 'forEachWith' 'async' [1..10] delay
944+-- S.'drain' $ S.'forEachWith' 'async' [1..10] delay
941-- where delay n = S.'yieldM' $ threadDelay (n * 1000000) >> print n
945-- where delay n = S.'yieldM' $ threadDelay (n * 1000000) >> print n
@@ -986,7 +990,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
986-- import "Streamly"
990-- import "Streamly"
987-- import qualified "Streamly.Prelude" as S
991-- import qualified "Streamly.Prelude" as S
989−-- main = 'drain' $ do
993+-- main = S.'drain' $ do
990-- x <- S.'fromFoldable' [3,2,1]
994-- x <- S.'fromFoldable' [3,2,1]
991-- delay x
995-- delay x
@@ -1008,7 +1012,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1008-- import "Streamly"
1012-- import "Streamly"
1009-- import qualified "Streamly.Prelude" as S
1013-- import qualified "Streamly.Prelude" as S
1015+-- import Control.Monad (forever)
1011−-- main = 'drain' $ forever $ S.yieldM getLine >>= S.yieldM . putStrLn
1017+-- main = S.'drain' $ forever $ S.yieldM getLine >>= S.yieldM . putStrLn
1014-- When multiple streams are composed using this style they nest in a DFS
1020-- When multiple streams are composed using this style they nest in a DFS
@@ -1020,7 +1026,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1020-- import "Streamly"
1026-- import "Streamly"
1021-- import qualified "Streamly.Prelude" as S
1027-- import qualified "Streamly.Prelude" as S
1023−-- main = 'drain' $ do
1029+-- main = S.'drain' $ do
1024-- x <- S.'fromFoldable' [1,2]
1030-- x <- S.'fromFoldable' [1,2]
1025-- y <- S.'fromFoldable' [3,4]
1031-- y <- S.'fromFoldable' [3,4]
1026-- S.'yieldM' $ putStrLn $ show (x, y)
1032-- S.'yieldM' $ putStrLn $ show (x, y)
@@ -1047,13 +1053,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1049-- import "Streamly"
1055-- import "Streamly"
1050−-- import "Streamly.Prelude" as S
1056+-- import qualified "Streamly.Prelude" as S
1052−-- comp = 'toList' . 'aheadly' $ do
1058+-- comp = S.'toList' . 'aheadly' $ do
1053-- x <- S.'fromFoldable' [3,2,1]
1059-- x <- S.'fromFoldable' [3,2,1]
1054-- delay x >> return x
1060-- delay x >> return x
1056−-- main = comp >> print
1062+-- main = comp >>= print
1059-- ThreadId 40: Delay 1
1065-- ThreadId 40: Delay 1
@@ -1088,9 +1094,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1090-- import "Streamly"
1096-- import "Streamly"
1091−-- import "Streamly.Prelude"
1097+-- import qualified "Streamly.Prelude" as S
1093−-- main = 'drain' . 'asyncly' $ do
1099+-- main = S.'drain' . 'asyncly' $ do
1094-- x <- S.'fromFoldable' [3,2,1]
1100-- x <- S.'fromFoldable' [3,2,1]
1095-- delay x
1101-- delay x
@@ -1117,7 +1123,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1117-- import "Streamly"
1123-- import "Streamly"
1118-- import qualified "Streamly.Prelude" as S
1124-- import qualified "Streamly.Prelude" as S
1120−-- main = 'drain' . 'asyncly' $ do
1126+-- main = S.'drain' . 'asyncly' $ do
1121-- x <- S.'fromFoldable' [1,2]
1127-- x <- S.'fromFoldable' [1,2]
1122-- y <- S.'fromFoldable' [3,4]
1128-- y <- S.'fromFoldable' [3,4]
1123-- S.'yieldM' $ putStrLn $ show (x, y)
1129-- S.'yieldM' $ putStrLn $ show (x, y)
@@ -1142,7 +1148,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1142-- import "Streamly"
1148-- import "Streamly"
1143-- import qualified "Streamly.Prelude" as S
1149-- import qualified "Streamly.Prelude" as S
1145−-- main = 'drain' . 'wSerially' $ do
1151+-- main = S.'drain' . 'wSerially' $ do
1146-- x <- S.'fromFoldable' [1,2]
1152-- x <- S.'fromFoldable' [1,2]
1147-- y <- S.'fromFoldable' [3,4]
1153-- y <- S.'fromFoldable' [3,4]
1148-- S.yieldM $ putStrLn $ show (x, y)
1154-- S.yieldM $ putStrLn $ show (x, y)
@@ -1170,7 +1176,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1170-- import "Streamly"
1176-- import "Streamly"
1171-- import qualified "Streamly.Prelude" as S
1177-- import qualified "Streamly.Prelude" as S
1173−-- main = 'drain' . 'wAsyncly' $ do
1179+-- main = S.'drain' . 'wAsyncly' $ do
1174-- x <- S.'fromFoldable' [1,2]
1180-- x <- S.'fromFoldable' [1,2]
1175-- y <- S.'fromFoldable' [3,4]
1181-- y <- S.'fromFoldable' [3,4]
1176-- S.'yieldM' $ putStrLn $ show (x, y)
1182-- S.'yieldM' $ putStrLn $ show (x, y)
@@ -1196,7 +1202,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1196-- import "Streamly"
1202-- import "Streamly"
1197-- import qualified "Streamly.Prelude" as S
1203-- import qualified "Streamly.Prelude" as S
1199−-- main = 'drain' . 'parallely' $ do
1205+-- main = S.'drain' . 'parallely' $ do
1200-- x <- S.'fromFoldable' [3,2,1]
1206-- x <- S.'fromFoldable' [3,2,1]
1201-- delay x
1207-- delay x
@@ -1234,11 +1240,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1234-- Now we can interpret this in whatever way we want:
1240-- Now we can interpret this in whatever way we want:
1237−-- main = 'drain' . 'serially' $ composed
1243+-- main = S.'drain' . 'serially' $ composed
1238−-- main = 'drain' . 'wSerially' $ composed
1244+-- main = S.'drain' . 'wSerially' $ composed
1239−-- main = 'drain' . 'asyncly' $ composed
1245+-- main = S.'drain' . 'asyncly' $ composed
1240−-- main = 'drain' . 'wAsyncly' $ composed
1246+-- main = S.'drain' . 'wAsyncly' $ composed
1241−-- main = 'drain' . 'parallely' $ composed
1247+-- main = S.'drain' . 'parallely' $ composed
1244-- As an exercise try to figure out the output of this code for each mode of
1250-- As an exercise try to figure out the output of this code for each mode of
@@ -1307,7 +1313,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1309-- 'Async' can run the iterations concurrently and therefore takes a total
1315-- 'Async' can run the iterations concurrently and therefore takes a total
1310−-- of 10 seconds (1 + 2 + 3 + 4):
1316+-- of 6 seconds which is max (1, 2) + max (3, 4):
1313-- main = (S.'toList' . 'asyncly' $ (,) \<$> s1 \<*> s2) >>= print
1319-- main = (S.'toList' . 'asyncly' $ (,) \<$> s1 \<*> s2) >>= print
@@ -1323,7 +1329,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1325-- Similarly 'WAsync' as well can run the iterations concurrently and
1331-- Similarly 'WAsync' as well can run the iterations concurrently and
1326−-- therefore takes a total of 10 seconds (1 + 2 + 3 + 4):
1332+-- therefore takes a total of 6 seconds (2 + 4):
1329-- main = (S.'toList' . 'wAsyncly' $ (,) \<$> s1 \<*> s2) >>= print
1335-- main = (S.'toList' . 'wAsyncly' $ (,) \<$> s1 \<*> s2) >>= print