on ec08681 help sign in
streamly/examples/AcidRain.hs
45 lines 1.4 kB history raw
1{-# LANGUAGE FlexibleContexts #-}
3-- This example is adapted from Gabriel Gonzalez's pipes-concurrency package.
4-- https://hackage.haskell.org/package/pipes-concurrency-2.0.8/docs/Pipes-Concurrent-Tutorial.html
6import Streamly
7import Control.Concurrent (threadDelay)
8import Control.Monad (when)
9import Control.Monad.IO.Class (MonadIO(liftIO))
10import Control.Monad.State (MonadState, get, modify, runStateT)
11import Data.Semigroup (cycle1)
13data Event = Harm Int | Heal Int | Quit deriving (Show)
15userAction :: MonadIO m => SerialT m Event
16userAction = cycle1 $ liftIO askUser
17 where
18 askUser = do
19 command <- getLine
20 case command of
21 "potion" -> return (Heal 10)
22 "quit" -> return Quit
23 _ -> putStrLn "What?" >> askUser
25acidRain :: MonadIO m => SerialT m Event
26acidRain = cycle1 $ liftIO (threadDelay 1000000) >> return (Harm 1)
28game :: (MonadAsync m, MonadState Int m) => SerialT m ()
29game = do
30 event <- userAction `parallel` acidRain
31 case event of
32 Harm n -> modify $ \h -> h - n
33 Heal n -> modify $ \h -> h + n
34 Quit -> fail "quit"
36 h <- get
37 when (h <= 0) $ fail "You die!"
38 liftIO $ putStrLn $ "Health = " ++ show h
40main :: IO ()
41main = do
42 putStrLn "Your health is deteriorating due to acid rain,\
43 \ type \"potion\" or \"quit\""
44 _ <- runStateT (runStream game) 60
45 return ()