on master help sign in
update examples and documentation
commit5fe13b0ef5eb9b79bba752097bbfff8ab2a46bc8 authorHarendra Kumar <harendra.kumar@gmail.com> dateSun 30 Dec 2018, 22:14 (8 years ago) parentd95c8c1
2 files changed+55−54
examples/MergeSort.hs+11−27 src/Streamly/Tutorial.hs+44−27
examples/MergeSort.hs+11−27
@@ -1,40 +1,24 @@
11{-# LANGUAGE FlexibleContexts #-}
22
3+-- | This example generates two streams sorted in ascending order and merges
4+-- them in ascending order, concurrently.
5+--
6+-- Compile with '-threaded -with-rtsopts "-N"' GHC options to use the
7+-- parallelism.
8+
39import Data.Word
410import System.Random (getStdGen, randoms)
511import Data.List (sort)
12+import Data.Ord (compare)
13+
614import Streamly
7−import Streamly.Prelude (yieldM)
8−import qualified Streamly.Prelude as A
15+import qualified Streamly.Prelude as S
916
1017getSorted :: Serial Word16
1118getSorted = do
12− g <- yieldM getStdGen
19+ g <- S.yieldM getStdGen
1320 let ls = take 100000 (randoms g) :: [Word16]
1421 foldMap return (sort ls)
1522
16−-- | merge two streams generating the elements from each in parallel
17−mergeAsync :: Ord a => Serial a -> Serial a -> Serial a
18−mergeAsync a b = do
19− x <- yieldM $ mkAsync a
20− y <- yieldM $ mkAsync b
21− merge x y
22−
23−merge :: Ord a => Serial a -> Serial a -> Serial a
24−merge a b = do
25− a1 <- yieldM $ A.uncons a
26− case a1 of
27− Nothing -> b
28− Just (x, ma) -> do
29− b1 <- yieldM $ A.uncons b
30− case b1 of
31− Nothing -> return x <> ma
32− Just (y, mb) ->
33− if y < x
34− then return y <> merge (return x <> ma) mb
35− else return x <> merge ma (return y <> mb)
36−
3723main :: IO ()
38−main = do
39− xs <- A.toList $ mergeAsync getSorted getSorted
40− print $ length xs
24+main = S.last (S.mergeAsyncBy compare getSorted getSorted) >>= print
src/Streamly/Tutorial.hs+44−27
@@ -87,8 +87,9 @@ module Streamly.Tutorial
8787 -- *** Parallel Asynchronous Composition ('Parallel')
8888 -- $parallel
8989
90− -- *** Custom composition
91− -- $custom
90+ -- XXX we should deprecate and remove the mkAsync API
91+ -- Custom composition
92+ -- custom
9293
9394 -- ** Monoid Style
9495 -- $monoid
@@ -892,6 +893,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
892893-- number of streams, as it will lead to an infinite sized scheduling queue.
893894--
894895
896+-- XXX to be removed
895897-- $custom
896898--
897899-- The 'mkAsync' API can be used to create references to asynchronously running
@@ -1439,7 +1441,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
14391441-- and operators instead of the ugly pragmas.
14401442--
14411443-- For more concurrent programming examples see,
1442−-- "ListDir.hs", "MergeSort.hs" and "SearchQuery.hs" in the examples directory.
1444+-- <src/examples/ListDir.hs ListDir.hs>,
1445+-- <src/examples/MergeSort.hs MergeSort.hs> and
1446+-- <src/examples/SearchQuery.hs SearchQuery.hs> in the examples directory.
14431447
14441448-- $reactive
14451449--
@@ -1462,52 +1466,65 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
14621466-- {-\# LANGUAGE FlexibleContexts #-}
14631467--
14641468-- import "Streamly"
1465−-- import Streamly.Prelude as S
1466−-- import Control.Monad (when)
1467−-- import Control.Monad.IO.Class (MonadIO(..))
1468−-- import Control.Monad.State (MonadState, get, modify, runStateT)
1469+-- import "Streamly.Prelude" as S
1470+-- import Control.Monad (void, when)
1471+-- import Control.Monad.IO.Class (MonadIO(liftIO))
1472+-- import Control.Monad.State (MonadState, get, modify, runStateT, put)
14691473--
1470−-- data Event = Harm Int | Heal Int | Quit deriving (Show)
1474+-- data Event = Quit | Harm Int | Heal Int deriving (Show)
14711475--
14721476-- userAction :: MonadAsync m => 'SerialT' m Event
1473−-- userAction = S.repeatM $ liftIO askUser
1477+-- userAction = S.'repeatM' $ liftIO askUser
14741478-- where
14751479-- askUser = do
14761480-- command <- getLine
14771481-- case command of
14781482-- "potion" -> return (Heal 10)
1479−-- "quit" -> return Quit
1480−-- _ -> putStrLn "What?" >> askUser
1483+-- "harm" -> return (Harm 10)
1484+-- "quit" -> return Quit
1485+-- _ -> putStrLn "Type potion or harm or quit" >> askUser
1486+--
1487+-- acidRain :: MonadAsync m => 'SerialT' m Event
1488+-- acidRain = 'asyncly' $ 'constRate' 1 $ S.'repeatM' $ liftIO $ return $ Harm 1
14811489--
1482−-- acidRain :: MonadAsync m => SerialT m Event
1483−-- acidRain = asyncly $ constRate 1 $ S.repeatM $ liftIO $ return $ Harm 1
1490+-- data Result = Check | Done
14841491--
1485−-- game :: ('MonadAsync' m, MonadState Int m) => 'SerialT' m ()
1486−-- game = do
1492+-- runEvents :: (MonadAsync m, MonadState Int m) => 'SerialT' m Result
1493+-- runEvents = do
14871494-- event \<- userAction \`parallel` acidRain
14881495-- case event of
1489−-- Harm n -> modify $ \\h -> h - n
1490−-- Heal n -> modify $ \\h -> h + n
1491−-- Quit -> fail "quit"
1492−--
1493−-- h <- get
1494−-- when (h <= 0) $ fail "You die!"
1495−-- liftIO $ putStrLn $ "Health = " ++ show h
1496−--
1496+-- Harm n -> modify (\\h -> h - n) >> return Check
1497+-- Heal n -> modify (\\h -> h + n) >> return Check
1498+-- Quit -> return Done
1499+--
1500+-- data Status = Alive | GameOver deriving Eq
1501+--
1502+-- getStatus :: (MonadAsync m, MonadState Int m) => Result -> m Status
1503+-- getStatus result =
1504+-- case result of
1505+-- Done -> liftIO $ putStrLn "You quit!" >> return GameOver
1506+-- Check -> do
1507+-- h <- get
1508+-- liftIO $ if (h <= 0)
1509+-- then putStrLn "You die!" >> return GameOver
1510+-- else putStrLn ("Health = " <> show h) >> return Alive
1511+--
1512+-- main :: IO ()
14971513-- main = do
14981514-- putStrLn "Your health is deteriorating due to acid rain,\\
14991515-- \\ type \\"potion\\" or \\"quit\\""
1500−-- _ <- runStateT ('runStream' game) 60
1501−-- return ()
1516+-- let runGame = S.'runWhile' (== Alive) $ S.'mapM' getStatus runEvents
1517+-- void $ runStateT runGame 60
15021518-- @
15031519--
15041520-- You can also find the source of this example in the examples directory as
1505−-- "AcidRain.hs". It has been adapted from Gabriel's
1521+-- <src/examples/AcidRain.hs AcidRain.hs>. It has been adapted from Gabriel's
15061522-- <https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html pipes-concurrency>
15071523-- package.
15081524-- This is much simpler compared to the pipes version because of the builtin
15091525-- concurrency in streamly. You can also find a SDL based reactive programming
1510−-- example adapted from Yampa in "Streamly.Examples.CirclingSquare".
1526+-- example adapted from Yampa in
1527+-- <src/examples/CirclingSquare.hs CirclingSquare.hs>.
15111528
15121529-- $performance
15131530--