Last active
August 29, 2015 14:19
-
-
Save Decoherence/d097e787deeb15db36e0 to your computer and use it in GitHub Desktop.
Example: Type-safe rocket launch using the Either monad transformer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Control.Monad.Trans | |
import Control.Monad.Trans.Either | |
import Safe | |
data Sensor = Temp | |
| Fuel | |
| Pressure | |
deriving Show | |
data Continue = Success Sensor | |
deriving Show | |
data Abort = Failure Sensor | |
deriving Show | |
type Value = Integer | |
type Range = (Value, Value) | |
-- | Return True if value within range | |
inRange :: Value -> Range -> Bool | |
inRange val (a, b) | |
| val >= a && val <= b = True | |
| otherwise = False | |
-- | Read sensor value and either Abort or Continue | |
check :: Sensor -> Range -> EitherT Abort IO Continue | |
check sensor (a,b) = do | |
lift $ putStrLn (show sensor ++ ": ") | |
val <- lift $ fmap (readNote "Expected numerical input.") getLine | |
if inRange val (a,b) | |
then right $ Success sensor | |
else left $ Failure sensor | |
-- | Perform all pre-flight checks in sequence, Abort immediately on Failure | |
goForLaunch :: IO (Either Abort Continue) | |
goForLaunch = runEitherT $ | |
check Fuel (100,200) | |
>> check Temp (30,100) | |
>> check Pressure (10,50) | |
-- | The main entry point. | |
main :: IO () | |
main = do | |
putStrLn "Beginning pre-launch checks..." | |
go <- goForLaunch | |
case go of | |
Left err -> do | |
print err | |
putStrLn "!! ABORT LAUNCH !!" | |
Right _ -> do | |
putStrLn "All systems go." | |
putStrLn "Lift off!" | |
{- | |
OUTPUT: | |
Beginning pre-launch checks... | |
Fuel: | |
150 | |
Temp: | |
45 | |
Pressure: | |
40 | |
All systems go. | |
Lift off! | |
-} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment