streamly-0.5.2: examples/AcidRain.hs
{-# LANGUAGE FlexibleContexts #-}
-- This example is adapted from Gabriel Gonzalez's pipes-concurrency package.
-- https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html
import Streamly
import Streamly.Prelude as S
import Control.Monad (when)
import Control.Monad.IO.Class (MonadIO(liftIO))
import Control.Monad.State (MonadState, get, modify, runStateT, put)
data Event = Harm Int | Heal Int deriving (Show)
userAction :: MonadAsync m => SerialT m Event
userAction = S.repeatM $ liftIO askUser
where
askUser = do
command <- getLine
case command of
"potion" -> return (Heal 10)
"quit" -> fail "quit"
_ -> putStrLn "What?" >> askUser
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
event <- userAction `parallel` acidRain
case event of
Harm n -> modify $ \h -> h - n
Heal n -> modify $ \h -> h + n
h <- get
when (h <= 0) $ fail "You die!"
liftIO $ putStrLn $ "Health = " <> show h
main :: IO ()
main = do
putStrLn "Your health is deteriorating due to acid rain,\
\ type \"potion\" or \"quit\""
_ <- runStateT (runStream game) 60
return ()