packages feed

streamly-0.5.2: test/loops.hs

import Streamly
import System.IO (stdout, hSetBuffering, BufferMode(LineBuffering))
import Streamly.Prelude (nil, yieldM)

main :: IO ()
main = do
    hSetBuffering stdout LineBuffering

    putStrLn "\nloopTail:\n"
    runStream $ do
        x <- loopTail 0
        yieldM $ print (x :: Int)

    putStrLn "\nloopHead:\n"
    runStream $ do
        x <- loopHead 0
        yieldM $ print (x :: Int)

    putStrLn "\nloopTailA:\n"
    runStream $ do
        x <- loopTailA 0
        yieldM $ print (x :: Int)

    putStrLn "\nloopHeadA:\n"
    runStream $ do
        x <- loopHeadA 0
        yieldM $ print (x :: Int)

    putStrLn "\nwSerial:\n"
    runStream $ do
        x <- (return 0 <> return 1) `wSerial` (return 100 <> return 101)
        yieldM $ print (x :: Int)

    putStrLn "\nParallel interleave:\n"
    runStream $ do
        x <- (return 0 <> return 1) `wAsync` (return 100 <> return 101)
        yieldM $ print (x :: Int)

    where

-------------------------------------------------------------------------------
-- Serial (single-threaded) stream generator loops
-------------------------------------------------------------------------------

    -- Generates a value and then loops. Can be used to generate an infinite
    -- stream. Interleaves the generator and the consumer.
    loopTail :: Int -> Serial Int
    loopTail x = do
        yieldM $ putStrLn "LoopTail..."
        return x <> (if x < 3 then loopTail (x + 1) else nil)

    -- 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 -> Serial Int
    loopHead x = do
        yieldM $ putStrLn "LoopHead..."
        (if x < 3 then loopHead (x + 1) else nil) <> return x

-------------------------------------------------------------------------------
-- Concurrent (multi-threaded) adaptive demand-based stream generator loops
-------------------------------------------------------------------------------

    loopTailA :: Int -> Serial Int
    loopTailA x = do
        yieldM $ putStrLn "LoopTailA..."
        return x `async` (if x < 3 then loopTailA (x + 1) else nil)

    loopHeadA :: Int -> Serial Int
    loopHeadA x = do
        yieldM $ putStrLn "LoopHeadA..."
        (if x < 3 then loopHeadA (x + 1) else nil) `async` return x

-------------------------------------------------------------------------------
-- Parallel (fairly scheduled, multi-threaded) stream generator loops
-------------------------------------------------------------------------------