Created
January 27, 2016 15:12
-
-
Save PolarNick239/3d6673f32638e977a7ad to your computer and use it in GitHub Desktop.
Haskell teletype
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
import Control.Monad.Free | |
import Control.Monad | |
import System.Exit | |
import Data.Traversable (traverse) | |
data TeletypeF next | |
= Say String next | |
| Ask (String -> next) | |
| Stop | |
instance Functor TeletypeF where | |
fmap f (Say msg next) = Say msg (f next) | |
fmap f (Ask k) = Ask (f . k) | |
fmap _ Stop = Stop | |
type Teletype = Free TeletypeF | |
say :: String -> Teletype () | |
say msg = liftF $ Say msg () | |
sayMany :: [String] -> Teletype () | |
sayMany [x] = say x | |
sayMany (x:xs) = say x >> sayMany xs | |
ask :: Teletype String | |
ask = liftF $ Ask id | |
askMany :: Int -> Teletype [String] | |
askMany 1 = fmap (\s -> [s]) ask | |
askMany n = do | |
x <- ask | |
xs <- askMany (n - 1) | |
return (x:xs) | |
stop :: Teletype () | |
stop = liftF Stop | |
telExample :: Teletype () | |
telExample = do | |
sayMany ["Hello!", "Hello!!!!!"] | |
say "What is your name?" | |
name <- ask | |
say "Tell your age and weight:" | |
[age, weight] <- askMany 2 | |
say $ "You are " ++ age ++ " years old. And your weight is " ++ weight | |
when (length name >= 10) stop | |
say $ "Hello, " ++ name ++ "!" | |
runIO :: Teletype a -> IO a | |
runIO (Pure r) = return r | |
runIO (Free (Say msg t)) = putStrLn msg >> runIO t | |
runIO (Free (Ask f )) = getLine >>= runIO . f | |
runIO (Free Stop ) = exitSuccess | |
simulate :: Teletype a -> [String] -> [String] | |
simulate (Pure _) _ = [] | |
simulate (Free Stop) _ = [] | |
simulate (Free (Say msg next)) l = msg : simulate next l | |
simulate (Free (Ask k)) (x:xs) = simulate (k x) xs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment