mirror of
https://github.com/ilyakooo0/streamly.git
synced 2024-11-04 14:27:15 +03:00
update examples and documentation
This commit is contained in:
parent
d95c8c1218
commit
5fe13b0ef5
@ -1,40 +1,24 @@
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
|
||||
-- | This example generates two streams sorted in ascending order and merges
|
||||
-- them in ascending order, concurrently.
|
||||
--
|
||||
-- Compile with '-threaded -with-rtsopts "-N"' GHC options to use the
|
||||
-- parallelism.
|
||||
|
||||
import Data.Word
|
||||
import System.Random (getStdGen, randoms)
|
||||
import Data.List (sort)
|
||||
import Data.Ord (compare)
|
||||
|
||||
import Streamly
|
||||
import Streamly.Prelude (yieldM)
|
||||
import qualified Streamly.Prelude as A
|
||||
import qualified Streamly.Prelude as S
|
||||
|
||||
getSorted :: Serial Word16
|
||||
getSorted = do
|
||||
g <- yieldM getStdGen
|
||||
g <- S.yieldM getStdGen
|
||||
let ls = take 100000 (randoms g) :: [Word16]
|
||||
foldMap return (sort ls)
|
||||
|
||||
-- | merge two streams generating the elements from each in parallel
|
||||
mergeAsync :: Ord a => Serial a -> Serial a -> Serial a
|
||||
mergeAsync a b = do
|
||||
x <- yieldM $ mkAsync a
|
||||
y <- yieldM $ mkAsync b
|
||||
merge x y
|
||||
|
||||
merge :: Ord a => Serial a -> Serial a -> Serial a
|
||||
merge a b = do
|
||||
a1 <- yieldM $ A.uncons a
|
||||
case a1 of
|
||||
Nothing -> b
|
||||
Just (x, ma) -> do
|
||||
b1 <- yieldM $ A.uncons b
|
||||
case b1 of
|
||||
Nothing -> return x <> ma
|
||||
Just (y, mb) ->
|
||||
if y < x
|
||||
then return y <> merge (return x <> ma) mb
|
||||
else return x <> merge ma (return y <> mb)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
xs <- A.toList $ mergeAsync getSorted getSorted
|
||||
print $ length xs
|
||||
main = S.last (S.mergeAsyncBy compare getSorted getSorted) >>= print
|
||||
|
@ -87,8 +87,9 @@ module Streamly.Tutorial
|
||||
-- *** Parallel Asynchronous Composition ('Parallel')
|
||||
-- $parallel
|
||||
|
||||
-- *** Custom composition
|
||||
-- $custom
|
||||
-- XXX we should deprecate and remove the mkAsync API
|
||||
-- Custom composition
|
||||
-- custom
|
||||
|
||||
-- ** Monoid Style
|
||||
-- $monoid
|
||||
@ -892,6 +893,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
|
||||
-- number of streams, as it will lead to an infinite sized scheduling queue.
|
||||
--
|
||||
|
||||
-- XXX to be removed
|
||||
-- $custom
|
||||
--
|
||||
-- The 'mkAsync' API can be used to create references to asynchronously running
|
||||
@ -1439,7 +1441,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
|
||||
-- and operators instead of the ugly pragmas.
|
||||
--
|
||||
-- For more concurrent programming examples see,
|
||||
-- "ListDir.hs", "MergeSort.hs" and "SearchQuery.hs" in the examples directory.
|
||||
-- <src/examples/ListDir.hs ListDir.hs>,
|
||||
-- <src/examples/MergeSort.hs MergeSort.hs> and
|
||||
-- <src/examples/SearchQuery.hs SearchQuery.hs> in the examples directory.
|
||||
|
||||
-- $reactive
|
||||
--
|
||||
@ -1462,52 +1466,65 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
|
||||
-- {-\# LANGUAGE FlexibleContexts #-}
|
||||
--
|
||||
-- import "Streamly"
|
||||
-- import Streamly.Prelude as S
|
||||
-- import Control.Monad (when)
|
||||
-- import Control.Monad.IO.Class (MonadIO(..))
|
||||
-- import Control.Monad.State (MonadState, get, modify, runStateT)
|
||||
-- import "Streamly.Prelude" as S
|
||||
-- import Control.Monad (void, when)
|
||||
-- import Control.Monad.IO.Class (MonadIO(liftIO))
|
||||
-- import Control.Monad.State (MonadState, get, modify, runStateT, put)
|
||||
--
|
||||
-- data Event = Harm Int | Heal Int | Quit deriving (Show)
|
||||
-- data Event = Quit | Harm Int | Heal Int deriving (Show)
|
||||
--
|
||||
-- userAction :: MonadAsync m => 'SerialT' m Event
|
||||
-- userAction = S.repeatM $ liftIO askUser
|
||||
-- userAction = S.'repeatM' $ liftIO askUser
|
||||
-- where
|
||||
-- askUser = do
|
||||
-- command <- getLine
|
||||
-- case command of
|
||||
-- "potion" -> return (Heal 10)
|
||||
-- "quit" -> return Quit
|
||||
-- _ -> putStrLn "What?" >> askUser
|
||||
-- "harm" -> return (Harm 10)
|
||||
-- "quit" -> return Quit
|
||||
-- _ -> putStrLn "Type potion or harm or quit" >> askUser
|
||||
--
|
||||
-- acidRain :: MonadAsync m => SerialT m Event
|
||||
-- acidRain = asyncly $ constRate 1 $ S.repeatM $ liftIO $ return $ Harm 1
|
||||
-- acidRain :: MonadAsync m => 'SerialT' m Event
|
||||
-- acidRain = 'asyncly' $ 'constRate' 1 $ S.'repeatM' $ liftIO $ return $ Harm 1
|
||||
--
|
||||
-- game :: ('MonadAsync' m, MonadState Int m) => 'SerialT' m ()
|
||||
-- game = do
|
||||
-- data Result = Check | Done
|
||||
--
|
||||
-- runEvents :: (MonadAsync m, MonadState Int m) => 'SerialT' m Result
|
||||
-- runEvents = do
|
||||
-- event \<- userAction \`parallel` acidRain
|
||||
-- case event of
|
||||
-- Harm n -> modify $ \\h -> h - n
|
||||
-- Heal n -> modify $ \\h -> h + n
|
||||
-- Quit -> fail "quit"
|
||||
-- Harm n -> modify (\\h -> h - n) >> return Check
|
||||
-- Heal n -> modify (\\h -> h + n) >> return Check
|
||||
-- Quit -> return Done
|
||||
--
|
||||
-- h <- get
|
||||
-- when (h <= 0) $ fail "You die!"
|
||||
-- liftIO $ putStrLn $ "Health = " ++ show h
|
||||
-- data Status = Alive | GameOver deriving Eq
|
||||
--
|
||||
-- getStatus :: (MonadAsync m, MonadState Int m) => Result -> m Status
|
||||
-- getStatus result =
|
||||
-- case result of
|
||||
-- Done -> liftIO $ putStrLn "You quit!" >> return GameOver
|
||||
-- Check -> do
|
||||
-- h <- get
|
||||
-- liftIO $ if (h <= 0)
|
||||
-- then putStrLn "You die!" >> return GameOver
|
||||
-- else putStrLn ("Health = " <> show h) >> return Alive
|
||||
--
|
||||
-- main :: IO ()
|
||||
-- main = do
|
||||
-- putStrLn "Your health is deteriorating due to acid rain,\\
|
||||
-- \\ type \\"potion\\" or \\"quit\\""
|
||||
-- _ <- runStateT ('runStream' game) 60
|
||||
-- return ()
|
||||
-- let runGame = S.'runWhile' (== Alive) $ S.'mapM' getStatus runEvents
|
||||
-- void $ runStateT runGame 60
|
||||
-- @
|
||||
--
|
||||
-- You can also find the source of this example in the examples directory as
|
||||
-- "AcidRain.hs". It has been adapted from Gabriel's
|
||||
-- <src/examples/AcidRain.hs AcidRain.hs>. It has been adapted from Gabriel's
|
||||
-- <https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html pipes-concurrency>
|
||||
-- package.
|
||||
-- This is much simpler compared to the pipes version because of the builtin
|
||||
-- concurrency in streamly. You can also find a SDL based reactive programming
|
||||
-- example adapted from Yampa in "Streamly.Examples.CirclingSquare".
|
||||
-- example adapted from Yampa in
|
||||
-- <src/examples/CirclingSquare.hs CirclingSquare.hs>.
|
||||
|
||||
-- $performance
|
||||
--
|
||||
|
Loading…
Reference in New Issue
Block a user