1import Control.Applicative ((<|>), empty)
2import Control.Concurrent (threadDelay, myThreadId)
3import Control.Monad.IO.Class (liftIO)
4import Data.Monoid ((<>))
5import System.Random (randomIO)
6import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
10 liftIO $ hSetBuffering stdout LineBuffering
12 putStrLn $ "\nloopTail:\n"
14 x <- loopTail (0 :: Int)
17 putStrLn $ "\nloopHead:\n"
19 x <- loopHead (0 :: Int)
22 putStrLn $ "\nloopTailA:\n"
24 x <- loopTailA (0 :: Int)
27 putStrLn $ "\nloopHeadA:\n"
29 x <- loopHeadA (0 :: Int)
32 putStrLn $ "\ninterleave:\n"
34 x <- return (0 :: Int) <> return 1 <=> return 100 <> return 101
37 putStrLn $ "\nParallel interleave:\n"
39 x <- return (0 :: Int) <> return 1 <|> return 100 <> return 101
44-------------------------------------------------------------------------------
45-- Serial (single-threaded) stream generator loops
46-------------------------------------------------------------------------------
48 -- In a <> composition the action on the left is executed and only after it
49 -- finished then the action on the right is executed. In other words the
50 -- actions are run serially.
52 -- Generates a value and then loops. Can be used to generate an infinite
53 -- stream. Interleaves the generator and the consumer.
54 loopTail :: Int -> AsyncT IO Int
56 liftIO $ putStrLn "LoopTail..."
57 return x <> (if x < 3 then loopTail (x + 1) else empty)
59 -- Loops and then generates a value. The consumer can run only after the
60 -- loop has finished. An infinite generator will not let the consumer run
62 loopHead :: Int -> AsyncT IO Int
64 liftIO $ putStrLn "LoopHead..."
65 (if x < 3 then loopHead (x + 1) else empty) <> return x
67-------------------------------------------------------------------------------
68-- Concurrent (multi-threaded) adaptive demand-based stream generator loops
69-------------------------------------------------------------------------------
71 -- In a <| composition the action on the left is executed first. However,
72 -- if it is not fast enough to generate results at the consumer's speed
73 -- then the action on the right is also spawned concurrently. In other
74 -- words, both actions may run concurrently based on the need.
76 loopTailA :: Int -> AsyncT IO Int
78 liftIO $ putStrLn "LoopTailA..."
79 return x <| (if x < 3 then loopTailA (x + 1) else empty)
81 loopHeadA :: Int -> AsyncT IO Int
83 liftIO $ putStrLn "LoopHeadA..."
84 (if x < 3 then loopHeadA (x + 1) else empty) <| return x
86-------------------------------------------------------------------------------
87-- Parallel (fairly scheduled, multi-threaded) stream generator loops
88-------------------------------------------------------------------------------
90 -- In a <|> composition both actions are run concurrently in a fair
91 -- manner, no one action is preferred over another. Both actions are
92 -- spawned right away in their own independent threads. In other words, the
93 -- actions will run concurrently.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list