on master help sign in
Do not use exceptions for error handling
f6ffd35Harendra Kumar
examples/AcidRain.hs+22−14
@@ -5,11 +5,11 @@
5
5
6import Streamly
6import Streamly
7import Streamly.Prelude as S
7import Streamly.Prelude as S
8−import Control.Monad (when)
8+import Control.Monad (void, when)
9import Control.Monad.IO.Class (MonadIO(liftIO))
9import Control.Monad.IO.Class (MonadIO(liftIO))
10import Control.Monad.State (MonadState, get, modify, runStateT, put)
10import Control.Monad.State (MonadState, get, modify, runStateT, put)
11
11
12−data Event = Harm Int | Heal Int deriving (Show)
12+data Event = Quit | Harm Int | Heal Int deriving (Show)
13
13
14userAction :: MonadAsync m => SerialT m Event
14userAction :: MonadAsync m => SerialT m Event
15userAction = S.repeatM $ liftIO askUser
15userAction = S.repeatM $ liftIO askUser
@@ -18,26 +18,34 @@ userAction = S.repeatM $ liftIO askUser
18 command <- getLine
18 command <- getLine
19 case command of
19 case command of
20 "potion" -> return (Heal 10)
20 "potion" -> return (Heal 10)
21− "quit" -> fail "quit"
21+ "harm" -> return (Harm 10)
22+ "quit" -> return Quit
22− _ -> putStrLn "What?" >> askUser
23+ _ -> putStrLn "Type potion or harm or quit" >> askUser
23
24
24acidRain :: MonadAsync m => SerialT m Event
25acidRain :: MonadAsync m => SerialT m Event
25acidRain = asyncly $ constRate 1 $ S.repeatM $ liftIO $ return $ Harm 1
26acidRain = asyncly $ constRate 1 $ S.repeatM $ liftIO $ return $ Harm 1
26
27
28+data Status = Check | Done
29+
27−game :: (MonadAsync m, MonadState Int m) => SerialT m ()
30+processEvents :: (MonadAsync m, MonadState Int m) => SerialT m Status
28−game = do
31+processEvents = do
29 event <- userAction `parallel` acidRain
32 event <- userAction `parallel` acidRain
30 case event of
33 case event of
31− Harm n -> modify $ \h -> h - n
34+ Harm n -> modify (\h -> h - n) >> return Check
32− Heal n -> modify $ \h -> h + n
35+ Heal n -> modify (\h -> h + n) >> return Check
33−
36+ Quit -> return Done
37+
38+checkStatus status =
39+ case status of
40+ Done -> liftIO $ putStrLn "You quit!" >> return False
41+ Check -> do
34− h <- get
42+ h <- get
35− when (h <= 0) $ fail "You die!"
43+ liftIO $ if (h <= 0)
36− liftIO $ putStrLn $ "Health = " <> show h
44+ then putStrLn "You die!" >> return False
45+ else putStrLn ("Health = " <> show h) >> return True
37
46
38main :: IO ()
47main :: IO ()
39main = do
48main = do
40 putStrLn "Your health is deteriorating due to acid rain,\
49 putStrLn "Your health is deteriorating due to acid rain,\
41 \ type \"potion\" or \"quit\""
50 \ type \"potion\" or \"quit\""
42− _ <- runStateT (runStream game) 60
51+ void $ runStateT (S.any (== False) $ S.mapM checkStatus $ processEvents) 60
43− return ()