on master help sign in
update some examples
5349a44Harendra Kumar
examples/loop.hs+72−9
@@ -1,16 +1,79 @@
1−import Control.Applicative ((<|>))
1+import Control.Applicative ((<|>), empty)
2−import Control.Concurrent (threadDelay)
2+import Control.Concurrent (threadDelay, myThreadId)
3import Control.Monad.IO.Class (liftIO)
3import Control.Monad.IO.Class (liftIO)
4+import Data.Monoid ((<>))
4import System.Random (randomIO)
5import System.Random (randomIO)
6+import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
5import Asyncly
7import Asyncly
6
8
7−main = wait_ $ do
9+main = do
8− x <- loop
10+ liftIO $ hSetBuffering stdout LineBuffering
11+
12+ runAsyncly $ do
13+ x <- loopTail (0 :: Int)
14+ liftIO $ print x
15+
16+ runAsyncly $ do
17+ x <- loopHead (0 :: Int)
18+ liftIO $ print x
19+
20+ runAsyncly $ do
21+ x <- loopTailA (0 :: Int)
22+ liftIO $ print x
23+
24+ runAsyncly $ do
25+ x <- loopHeadA (0 :: Int)
9− liftIO $ print x
26+ liftIO $ print x
10
27
11 where
28 where
12
29
13− loop = do
30+-------------------------------------------------------------------------------
14− liftIO $ threadDelay 1000000
31+-- Serial (single-threaded) stream generator loops
15− x <- liftIO (randomIO :: IO Int)
32+-------------------------------------------------------------------------------
16− return x <|> loop
33+
34+ -- In a <> composition the action on the left is executed and only after it
35+ -- finished then the action on the right is executed. In other words the
36+ -- actions are run serially.
37+
38+ -- Generates a value and then loops. Can be used to generate an infinite
39+ -- stream. Interleaves the generator and the consumer.
40+ loopTail :: Int -> AsynclyT IO Int
41+ loopTail x = do
42+ liftIO $ putStrLn "LoopTail..."
43+ return x <> (if x < 3 then loopTail (x + 1) else empty)
44+
45+ -- Loops and then generates a value. The consumer can run only after the
46+ -- loop has finished. An infinite generator will not let the consumer run
47+ -- at all.
48+ loopHead :: Int -> AsynclyT IO Int
49+ loopHead x = do
50+ liftIO $ putStrLn "LoopHead..."
51+ (if x < 3 then loopHead (x + 1) else empty) <> return x
52+
53+-------------------------------------------------------------------------------
54+-- Concurrent (multi-threaded) adaptive demand-based stream generator loops
55+-------------------------------------------------------------------------------
56+
57+ -- In a <|> composition the action on the left is executed first. However,
58+ -- if it is not fast enough to generate results at the consumer's speed
59+ -- then the action on the right is also spawned concurrently. In other
60+ -- words, both actions may run concurrently based on the need.
61+
62+ loopTailA :: Int -> AsynclyT IO Int
63+ loopTailA x = do
64+ liftIO $ putStrLn "LoopTailA..."
65+ return x <|> (if x < 3 then loopTailA (x + 1) else empty)
66+
67+ loopHeadA :: Int -> AsynclyT IO Int
68+ loopHeadA x = do
69+ liftIO $ putStrLn "LoopHeadA..."
70+ (if x < 3 then loopHeadA (x + 1) else empty) <|> return x
71+
72+-------------------------------------------------------------------------------
73+-- Parallel (fairly scheduled, multi-threaded) stream generator loops
74+-------------------------------------------------------------------------------
75+
76+ -- In a <||> composition both actions are run concurrently in a fair
77+ -- manner, no one action is preferred over another. Both actions are
78+ -- spawned right away in their own independent threads. In other words, the
79+ -- actions will run concurrently.
examples/map-reduce.hs+2−6
@@ -1,10 +1,6 @@
1−import Control.Applicative ((<|>), empty)
2−import Control.Monad.IO.Class (liftIO)
3import Data.List (sum)
1import Data.List (sum)
4import Asyncly
2import Asyncly
5
3
6main = do
4main = do
7− squares <- wait $ do
5+ xs <- toList $ for [1..100] $ \x -> return (x * x) :: AsynclyT IO Int
8− x <- foldl (<|>) empty $ map return [1..100]
9− return (x * x)
10− print . sum $ squares
6+ print . sum $ xs