@@ -103,7 +103,7 @@ module Streamly.Tutorial
103 -- * Summary of Compositions
103 -- * Summary of Compositions
104 -- $compositionSummary
104 -- $compositionSummary
106− -- * Concurrent Programming Examples
106+ -- * Concurrent Programming
107 -- $concurrent
107 -- $concurrent
109 -- * Reactive Programming
109 -- * Reactive Programming
@@ -766,12 +766,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
767-- $concurrent
767-- $concurrent
769−-- There are two ways to achieve concurrency. We can generate individual
769+-- When writing concurrent programs there are two distinct places where the
770−-- elements of a stream concurrently by folding with parallel composition
770+-- programmer chooses the type of concurrency. First, when /generating/ a
771−-- operators i.e. '<|' or '<|>'. 'forEachWith' can be useful in such cases.
771+-- stream by combining other streams we can use one of the sum style operators
772+-- to combine them concurrently or serially. Second, when /processing/ a stream
773+-- in a monadic composition we can choose one of the monad composition types to
774+-- choose the desired type of concurrency.
773−-- In the following example, we square each number concurrently but then
776+-- In the following example the squares of @x@ and @y@ are computed
774−-- sum and print them serially:
777+-- concurrently using the '<|' operator and the square roots of their sum are
778+-- also computed concurrently by using the 'asyncly' combinator. We can choose
779+-- different combinators e.g. '<>' and 'serially', to control the concurrency.
777-- import "Streamly"
782-- import "Streamly"
@@ -779,26 +784,19 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
779-- import Data.List (sum)
784-- import Data.List (sum)
781-- main = do
786-- main = do
782−-- squares \<- 'toList' $ 'serially' $ 'forEachWith' ('<|') [1..100] $ \\x -\> return $ x * x
783−-- print $ sum squares
786−-- The following example not just computes the squares concurrently but also
787−-- computes the square root of their sums concurrently by using the parallel
792−-- import "Streamly.Prelude" (toList)
793−-- import Data.List (sum)
796−-- z \<- 'toList' $ 'asyncly' $ do
787+-- z \<- 'toList'
788+-- $ 'asyncly' -- Concurrent monadic processing (sqrt below)
797−-- xsq \<- 'forEachWith' ('<|') [1..100] $ \\x -> return $ x * x
790+-- x2 \<- 'forEachWith' ('<|') [1..100] $ -- Concurrent @for@ loop
791+-- \\x -> return $ x * x -- body of the loop
798−-- ysq \<- 'forEachWith' ('<|') [1..100] $ \\x -> return $ x * x
792+-- y2 \<- 'forEachWith' ('<|') [1..100] $
793+-- \\y -> return $ y * y
799−-- return $ sqrt (xsq + ysq)
794+-- return $ sqrt (x2 + y2)
800-- print $ sum z
795-- print $ sum z
798+-- You can see how this directly maps to the imperative style
799+-- <https://en.wikipedia.org/wiki/OpenMP OpenMP> model.
803-- $reactive
801-- $reactive