Skip to content

Instantly share code, notes, and snippets.

@radix
Created September 19, 2015 17:27
Show Gist options
  • Save radix/f7ac6243d4d16fdb5789 to your computer and use it in GitHub Desktop.
Save radix/f7ac6243d4d16fdb5789 to your computer and use it in GitHub Desktop.
free monad DSL without a terminal case
{-# LANGUAGE DeriveFunctor, FlexibleInstances, ExistentialQuantification, RankNTypes #-}
import Control.Monad.Free
class Monad m => MyEffects m where
prompt :: String -> m String
display :: String -> m ()
-- end :: m ()
data DSL next
= Prompt String (String -> next)
| Display String next
-- | End
deriving (Show, Functor)
instance MyEffects (Free DSL) where
prompt p = liftF (Prompt p id)
display o = liftF (Display o ())
-- end = end'
runIO :: (Free DSL a) -> IO a
runIO (Free (Prompt p cont)) = do putStr p; line <- getLine; runIO (cont line)
runIO (Free (Display o cont)) = do putStrLn o; runIO cont
runIO (Pure x) = return x
greet :: MyEffects m => m String
greet = do
name <- prompt "Enter your name: "
let greeting = "Why hello there, " ++ name ++ "."
display greeting
friendName <- prompt "And what is your friend's name? "
display ("It's good to meet you too, " ++ friendName ++ ".")
return "blacrg"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment