mirror of
https://github.com/composewell/streamly.git
synced 2024-11-11 00:53:46 +03:00
a74a0c0844
Streamly is a more appropriate name and conveys the core idea. Stream concurrently = streamly.
89 lines
3.2 KiB
Haskell
89 lines
3.2 KiB
Haskell
import Streamly
|
|
import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
|
|
|
|
main = do
|
|
liftIO $ hSetBuffering stdout LineBuffering
|
|
|
|
putStrLn $ "\nloopTail:\n"
|
|
runStreamT $ do
|
|
x <- loopTail 0
|
|
liftIO $ print (x :: Int)
|
|
|
|
putStrLn $ "\nloopHead:\n"
|
|
runStreamT $ do
|
|
x <- loopHead 0
|
|
liftIO $ print (x :: Int)
|
|
|
|
putStrLn $ "\nloopTailA:\n"
|
|
runStreamT $ do
|
|
x <- loopTailA 0
|
|
liftIO $ print (x :: Int)
|
|
|
|
putStrLn $ "\nloopHeadA:\n"
|
|
runStreamT $ do
|
|
x <- loopHeadA 0
|
|
liftIO $ print (x :: Int)
|
|
|
|
putStrLn $ "\ninterleave:\n"
|
|
runStreamT $ do
|
|
x <- return 0 <> return 1 <=> return 100 <> return 101
|
|
liftIO $ print (x :: Int)
|
|
|
|
putStrLn $ "\nParallel interleave:\n"
|
|
runStreamT $ do
|
|
x <- return 0 <> return 1 <|> return 100 <> return 101
|
|
liftIO $ print (x :: Int)
|
|
|
|
where
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Serial (single-threaded) stream generator loops
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- In a <> composition the action on the left is executed and only after it
|
|
-- finished then the action on the right is executed. In other words the
|
|
-- actions are run serially.
|
|
|
|
-- Generates a value and then loops. Can be used to generate an infinite
|
|
-- stream. Interleaves the generator and the consumer.
|
|
loopTail :: Int -> StreamT IO Int
|
|
loopTail x = do
|
|
liftIO $ putStrLn "LoopTail..."
|
|
return x <> (if x < 3 then loopTail (x + 1) else empty)
|
|
|
|
-- Loops and then generates a value. The consumer can run only after the
|
|
-- loop has finished. An infinite generator will not let the consumer run
|
|
-- at all.
|
|
loopHead :: Int -> StreamT IO Int
|
|
loopHead x = do
|
|
liftIO $ putStrLn "LoopHead..."
|
|
(if x < 3 then loopHead (x + 1) else empty) <> return x
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Concurrent (multi-threaded) adaptive demand-based stream generator loops
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- In a <| composition the action on the left is executed first. However,
|
|
-- if it is not fast enough to generate results at the consumer's speed
|
|
-- then the action on the right is also spawned concurrently. In other
|
|
-- words, both actions may run concurrently based on the need.
|
|
|
|
loopTailA :: Int -> StreamT IO Int
|
|
loopTailA x = do
|
|
liftIO $ putStrLn "LoopTailA..."
|
|
return x <| (if x < 3 then loopTailA (x + 1) else empty)
|
|
|
|
loopHeadA :: Int -> StreamT IO Int
|
|
loopHeadA x = do
|
|
liftIO $ putStrLn "LoopHeadA..."
|
|
(if x < 3 then loopHeadA (x + 1) else empty) <| return x
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Parallel (fairly scheduled, multi-threaded) stream generator loops
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- In a <|> composition both actions are run concurrently in a fair
|
|
-- manner, no one action is preferred over another. Both actions are
|
|
-- spawned right away in their own independent threads. In other words, the
|
|
-- actions will run concurrently.
|