[Haskell-cafe] background question about IO monad
ryani.spam at gmail.com
Thu Feb 7 18:14:54 EST 2008
On 2/6/08, Uwe Hollerbach <uhollerbach at gmail.com> wrote:
> And, coming back to my scheme interpreter, this is at least somewhat
> irrelevant, because, since I am in a REPL of my own devising, I'm
> firmly in IO-monad-land, now and forever.
This is not entirely true; a REPL can be pure.
Consider the following simple stack-based-calculator; all the IO
happens within "interact", the REPL itself is pure:
main = hSetBuffering stdout NoBuffering >> interact replMain
replMain s = "Stack calculator\n> " ++ repl  s
repl :: [Int] -> String -> String
repl _  = ""
repl _ ('q':_) = ""
repl s ('\n':xs) = show s ++ "\n> " ++ repl s xs
repl s xs@(x:_) | x >= '0' && x <= '9' =
let (v, xs') = head $ reads xs in repl (v:s) xs'
repl s (c:xs) | c `elem` validCommands = case command c s of
Just s' -> repl s' xs
Nothing -> "<stack underflow>\n" ++ repl s xs
repl s (_:xs) = repl s xs -- ignore unrecognized characters
validCommands = ".d+c"
command :: Char -> [Int] -> Maybe [Int]
command '.' (x:xs) = Just xs
command 'd' (x:xs) = Just $ x:x:xs
command '+' (x:y:xs) = Just $ (x+y):xs
command 'c' _ = Just 
command _ _ = Nothing
You can go further than "interact" if you want to abstract away the
impurity in your system and take input from some outside process which
has a limited set of impure operations. Take a look here for an
example using "Prompt" (which has seen some discussion here on
In that example, "guess n" is an action in the pure Prompt monad;
different interpretation functions allow this monad to interact with
an AI (in a semi-pure setting; it outputs strings), or with a real
player via the full IO interface. A similar mechanism could be used
for the scheme REPL to make it as "pure" as possible, with
"getClockTime" being replaced by "prompt GetClockTime" to interact
with the outside world.
More information about the Haskell-Cafe