Last active
January 8, 2025 03:34
-
-
Save roboguy13/f2643d4f67ccc799790f1ca9ce6e0422 to your computer and use it in GitHub Desktop.
This file contains 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
{-# LANGUAGE GADTs #-} | |
import Control.Monad | |
-- Note that Cmd values are perfectly "pure" values. There's nothing here that | |
-- makes them impure. | |
data Cmd a where | |
PutStr :: String -> Cmd () | |
PutStrLn :: String -> Cmd () | |
ReadLn :: Cmd Int | |
Pure :: a -> Cmd a | |
Bind :: Cmd a -> (a -> Cmd b) -> Cmd b | |
instance Functor Cmd where | |
fmap f x = x >>= pure . f | |
instance Applicative Cmd where | |
pure = Pure | |
(<*>) = ap | |
instance Monad Cmd where | |
return = pure | |
(>>=) = Bind | |
-- This is a Cmd, which is a perfectly pure value | |
example :: Cmd () | |
example = do | |
PutStr "Enter a number: " | |
a <- ReadLn | |
PutStr "Enter another number: " | |
b <- ReadLn | |
let c = a + b | |
PutStrLn $ "first + second = " ++ show c | |
if c < 10 | |
then PutStrLn "This is less than 10" | |
else PutStrLn "This is greater than or equal to 10" | |
main :: IO () | |
main = run example | |
-- | |
-- Interpret as IO. We could interpret this in other ways too! | |
-- | |
run :: Cmd a -> IO a | |
run (PutStr s) = putStr s | |
run (PutStrLn s) = putStrLn s | |
run ReadLn = readLn | |
run (Pure x) = pure x | |
run (Bind m f) = do | |
x <- run m | |
run (f x) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment