@@ -170,7 +170,7 @@ module Streamly.Tutorial
170170 )
171171where
172172
173−import Streamly
173+import Streamly hiding (foldWith, foldMapWith, forEachWith)
174174import Streamly.Prelude
175175import Data.Semigroup
176176import Control.Applicative
@@ -332,9 +332,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
332332-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
333333--
334334-- @
335−-- > 'drain' $ liftIO $ putStrLn "Hello world!"
335+-- > S.'drain' $ liftIO $ putStrLn "Hello world!"
336336-- Hello world!
337−-- > 'drain' $ lift $ putStrLn "Hello world!"
337+-- > S.'drain' $ lift $ putStrLn "Hello world!"
338338-- Hello world!
339339-- @
340340--
@@ -348,6 +348,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
348348-- > import "Streamly"
349349-- > import "Streamly.Prelude" ((|:))
350350-- > import qualified "Streamly.Prelude" as S
351+--
352+-- > import Control.Concurrent
351353-- @
352354--
353355-- 'nil' represents an empty stream and 'consM' or its operator form '|:' adds
@@ -370,7 +372,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
370372-- @
371373-- > S.'toList' $ 'pure' 1
372374-- [1]
373−-- > S.'toList' $ 'yield' 1
375+-- > S.'toList' $ S.'yield' 1
374376-- [1]
375377-- > S.'toList' $ S.'yieldM' 'getLine'
376378-- hello
@@ -391,7 +393,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
391393-- right fold using 'consM' and 'nil':
392394--
393395-- @
394−-- > 'drain' $ 'Prelude.foldr' ('|:') S.'nil' ['putStr' "Hello ", 'putStrLn' "world!"]
396+-- > S.'drain' $ 'Prelude.foldr' ('|:') S.'nil' ['putStr' "Hello ", 'putStrLn' "world!"]
395397-- Hello world!
396398-- @
397399--
@@ -418,7 +420,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
418420-- The following finishes in 10 seconds (100 seconds when serial):
419421--
420422-- @
421−-- > 'drain' $ 'asyncly' $ S.'replicateM' 10 $ p 10
423+-- > S.drain $ 'asyncly' $ S.'replicateM' 10 $ p 10
422424-- @
423425--
424426
@@ -445,7 +447,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
445447-- forever:
446448--
447449-- @
448−-- > 'drain' $ S.'repeatM' getLine & S.'mapM' putStrLn
450+-- > import Data.Function ((&))
451+-- > S.'drain' $ S.'repeatM' getLine & S.'mapM' putStrLn
449452-- @
450453--
451454-- The following code snippet reads lines from standard input, filters blank
@@ -458,7 +461,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
458461-- import Data.Char (toUpper)
459462-- import Data.Function ((&))
460463--
461−-- main = 'drain' $
464+-- main = S.'drain' $
462465-- S.'repeatM' getLine
463466-- & S.'filter' (not . null)
464467-- & S.'drop' 1
@@ -479,7 +482,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
479482--
480483-- @
481484-- > 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))
483486-- @
484487--
485488
@@ -494,7 +497,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
494497--
495498-- @
496499-- > 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)
498501-- @
499502
500503-- $semigroup
@@ -550,7 +553,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
550553-- 3, 4:
551554--
552555-- @
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)
554557-- @
555558-- @
556559-- 1
@@ -564,7 +567,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
564567-- same thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
565568--
566569-- @
567−-- main = 'drain' $ delay 3 <> delay 2 <> delay 1
570+-- main = S.'drain' $ delay 3 <> delay 2 <> delay 1
568571-- @
569572-- @
570573-- ThreadId 36: Delay 3
@@ -577,7 +580,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
577580-- irrespective of the type of stream:
578581--
579582-- @
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)
581584-- @
582585
583586-- $interleaved
@@ -594,7 +597,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
594597-- The following example prints the sequence 1, 3, 2, 4
595598--
596599-- @
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)
598601-- @
599602-- @
600603-- 1
@@ -609,7 +612,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
609612-- thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
610613--
611614-- @
612−-- main = 'drain' . 'wSerially' $ delay 3 <> delay 2 <> delay 1
615+-- main = S.'drain' . 'wSerially' $ delay 3 <> delay 2 <> delay 1
613616-- @
614617-- @
615618-- ThreadId 36: Delay 3
@@ -623,7 +626,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
623626-- combinator in the following example:
624627--
625628-- @
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)
627630-- @
628631-- @
629632-- 1
@@ -653,7 +656,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
653656--
654657-- @
655658-- 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)
657660-- print xs
658661-- where p n = threadDelay 1000000 >> return n
659662-- @
@@ -690,7 +693,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
690693--
691694-- @
692695-- 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)
694697-- print xs
695698-- where p n = threadDelay 1000000 >> return n
696699-- @
@@ -705,7 +708,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
705708--
706709-- @
707710-- 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)
709712-- print xs
710713-- where p n = threadDelay 1000000 >> return n
711714-- @
@@ -719,7 +722,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
719722-- (3, 2, 1) = 3@ seconds:
720723--
721724-- @
722−-- main = 'drain' . 'asyncly' $ delay 3 '<>' delay 2 '<>' delay 1
725+-- main = S.'drain' . 'asyncly' $ delay 3 '<>' delay 2 '<>' delay 1
723726-- @
724727-- @
725728-- ThreadId 42: Delay 1
@@ -738,7 +741,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
738741-- second as all of the actions are concurrent.
739742--
740743-- @
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)
742745-- @
743746-- @
744747-- 1
@@ -755,7 +758,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
755758-- even if none of them blocks:
756759--
757760-- @
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)
759762-- where traced m = S.'yieldM' (myThreadId >>= print) >> return m
760763-- @
761764-- @
@@ -773,7 +776,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
773776-- not used the 'asyncly' combinator in the following example:
774777--
775778-- @
776−-- main = 'drain' $ delay 3 \`async` delay 2 \`async` delay 1
779+-- main = S.'drain' $ delay 3 \`async` delay 2 \`async` delay 1
777780-- @
778781-- @
779782-- ThreadId 42: Delay 1
@@ -789,11 +792,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
789792-- all computations at once for any reason 'Parallel' style must be used
790793-- instead.
791794--
792−-- 'Async' style should be preferred over 'Parallel' or 'WAsync' unless you
793−-- really need those. It utilizes the resources optimally. It should be used
795+-- 'Async' style utilizes resources optimally and should be preferred over
796+-- 'Parallel' or 'WAsync' unless you really need those. 'Async' should be used
794797-- when we know that the computations can run in parallel but we do not care if
795798-- 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
797800-- infinite number of streams in contrast to the 'Parallel' or 'WAsync' styles,
798801-- because it does not require us to run all of them at the same time in a fair
799802-- manner.
@@ -816,7 +819,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
816819-- first traversal order but this is not guaranteed.
817820--
818821-- @
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)
820823-- @
821824-- @
822825-- 1
@@ -831,7 +834,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
831834-- the 'wAsyncly' combinator in the following example:
832835--
833836-- @
834−-- main = 'drain' $ delay 3 \`wAsync` delay 2 \`wAsync` delay 1
837+-- main = S.'drain' $ delay 3 \`wAsync` delay 2 \`wAsync` delay 1
835838-- @
836839-- @
837840-- ThreadId 42: Delay 1
@@ -866,14 +869,15 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
866869--
867870-- The following example sends a query to all the three search engines in
868871-- 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:
870874--
871875-- @
872876-- import "Streamly"
873877-- import qualified Streamly.Prelude as S
874878-- import Network.HTTP.Simple
875879--
876−-- main = 'drain' . 'parallely' $ google \<> bing \<> duckduckgo
880+-- main = S.'drain' . 'parallely' $ google \<> bing \<> duckduckgo
877881-- where
878882-- google = get "https://www.google.com/search?q=haskell"
879883-- bing = get "https://www.bing.com/search?q=haskell"
@@ -887,7 +891,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
887891-- 'parallely' combinator in the following example:
888892--
889893-- @
890−-- main = 'drain' $ delay 3 \`parallel` delay 2 \`wAsync` delay 1
894+-- main = S.'drain' $ delay 3 \`parallel` delay 2 \`wAsync` delay 1
891895-- @
892896-- @
893897-- ThreadId 42: Delay 1
@@ -934,10 +938,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
934938-- import Control.Concurrent
935939--
936940-- main = do
937−-- 'drain' $ 'asyncly' $ foldMap delay [1..10]
938−-- 'drain' $ 'foldWith' 'async' (map delay [1..10])
939−-- 'drain' $ 'foldMapWith' 'async' delay [1..10]
940−-- 'drain' $ 'forEachWith' 'async' [1..10] delay
941+-- S.'drain' $ 'asyncly' $ foldMap delay [1..10]
942+-- S.'drain' $ S.'foldWith' 'async' (map delay [1..10])
943+-- S.'drain' $ S.'foldMapWith' 'async' delay [1..10]
944+-- S.'drain' $ S.'forEachWith' 'async' [1..10] delay
941945-- where delay n = S.'yieldM' $ threadDelay (n * 1000000) >> print n
942946-- @
943947
@@ -986,7 +990,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
986990-- import "Streamly"
987991-- import qualified "Streamly.Prelude" as S
988992--
989−-- main = 'drain' $ do
993+-- main = S.'drain' $ do
990994-- x <- S.'fromFoldable' [3,2,1]
991995-- delay x
992996-- @
@@ -1008,7 +1012,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10081012-- import "Streamly"
10091013-- import qualified "Streamly.Prelude" as S
10101014--
1011−-- main = 'drain' $ forever $ S.yieldM getLine >>= S.yieldM . putStrLn
1015+-- import Control.Monad (forever)
1016+--
1017+-- main = S.'drain' $ forever $ S.yieldM getLine >>= S.yieldM . putStrLn
10121018-- @
10131019--
10141020-- When multiple streams are composed using this style they nest in a DFS
@@ -1020,7 +1026,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10201026-- import "Streamly"
10211027-- import qualified "Streamly.Prelude" as S
10221028--
1023−-- main = 'drain' $ do
1029+-- main = S.'drain' $ do
10241030-- x <- S.'fromFoldable' [1,2]
10251031-- y <- S.'fromFoldable' [3,4]
10261032-- S.'yieldM' $ putStrLn $ show (x, y)
@@ -1047,13 +1053,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10471053--
10481054-- @
10491055-- import "Streamly"
1050−-- import "Streamly.Prelude" as S
1056+-- import qualified "Streamly.Prelude" as S
10511057--
1052−-- comp = 'toList' . 'aheadly' $ do
1058+-- comp = S.'toList' . 'aheadly' $ do
10531059-- x <- S.'fromFoldable' [3,2,1]
10541060-- delay x >> return x
10551061--
1056−-- main = comp >> print
1062+-- main = comp >>= print
10571063-- @
10581064-- @
10591065-- ThreadId 40: Delay 1
@@ -1088,9 +1094,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10881094--
10891095-- @
10901096-- import "Streamly"
1091−-- import "Streamly.Prelude"
1097+-- import qualified "Streamly.Prelude" as S
10921098--
1093−-- main = 'drain' . 'asyncly' $ do
1099+-- main = S.'drain' . 'asyncly' $ do
10941100-- x <- S.'fromFoldable' [3,2,1]
10951101-- delay x
10961102-- @
@@ -1117,7 +1123,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11171123-- import "Streamly"
11181124-- import qualified "Streamly.Prelude" as S
11191125--
1120−-- main = 'drain' . 'asyncly' $ do
1126+-- main = S.'drain' . 'asyncly' $ do
11211127-- x <- S.'fromFoldable' [1,2]
11221128-- y <- S.'fromFoldable' [3,4]
11231129-- S.'yieldM' $ putStrLn $ show (x, y)
@@ -1142,7 +1148,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11421148-- import "Streamly"
11431149-- import qualified "Streamly.Prelude" as S
11441150--
1145−-- main = 'drain' . 'wSerially' $ do
1151+-- main = S.'drain' . 'wSerially' $ do
11461152-- x <- S.'fromFoldable' [1,2]
11471153-- y <- S.'fromFoldable' [3,4]
11481154-- S.yieldM $ putStrLn $ show (x, y)
@@ -1170,7 +1176,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11701176-- import "Streamly"
11711177-- import qualified "Streamly.Prelude" as S
11721178--
1173−-- main = 'drain' . 'wAsyncly' $ do
1179+-- main = S.'drain' . 'wAsyncly' $ do
11741180-- x <- S.'fromFoldable' [1,2]
11751181-- y <- S.'fromFoldable' [3,4]
11761182-- S.'yieldM' $ putStrLn $ show (x, y)
@@ -1196,7 +1202,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11961202-- import "Streamly"
11971203-- import qualified "Streamly.Prelude" as S
11981204--
1199−-- main = 'drain' . 'parallely' $ do
1205+-- main = S.'drain' . 'parallely' $ do
12001206-- x <- S.'fromFoldable' [3,2,1]
12011207-- delay x
12021208-- @
@@ -1234,11 +1240,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
12341240-- Now we can interpret this in whatever way we want:
12351241--
12361242-- @
1237−-- main = 'drain' . 'serially' $ composed
1238−-- main = 'drain' . 'wSerially' $ composed
1239−-- main = 'drain' . 'asyncly' $ composed
1240−-- main = 'drain' . 'wAsyncly' $ composed
1241−-- main = 'drain' . 'parallely' $ composed
1243+-- main = S.'drain' . 'serially' $ composed
1244+-- main = S.'drain' . 'wSerially' $ composed
1245+-- main = S.'drain' . 'asyncly' $ composed
1246+-- main = S.'drain' . 'wAsyncly' $ composed
1247+-- main = S.'drain' . 'parallely' $ composed
12421248-- @
12431249--
12441250-- 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))
13071313-- @
13081314--
13091315-- '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):
13111317--
13121318-- @
13131319-- main = (S.'toList' . 'asyncly' $ (,) \<$> s1 \<*> s2) >>= print
@@ -1323,7 +1329,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
13231329-- @
13241330--
13251331-- 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):
13271333--
13281334-- @
13291335-- main = (S.'toList' . 'wAsyncly' $ (,) \<$> s1 \<*> s2) >>= print