On 2/6/08, Uwe Hollerbach <[EMAIL PROTECTED]> 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:
import System.IO
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
haskell-cafe): http://paste.lisp.org/display/53766
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.
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe