
Dear all, We've been working on bulding an interpreter in haskell and we seem to have encountered a problem. At the end of the email I've pasted a minimal version of the program, that shows the error. The problem is that we 'putStr' a prompt onto (unbuffered) stdout and then read a line, process it and 'print' output, all very basic. This is done in the function 'processline' and works fine is this function is used directly from 'main', however, if used from within the 'while' construct it fails. In the 'while' context it appears that the 'getLine' is executed before the 'putStr' is (or perhaps stdout is not as 'unbuffered' as we expect ?). As all the functions in this example are sequenced in the context of the IO monad, I guess that order of execution should be predefined, right ? Any help would be greatly appreciated, just for information: we tested with GHC 5.02.1 and 5.02.2. Kind regards, Alex... ---- import IO import Monad notM :: Monad m => m Bool -> m Bool notM = liftM not processline :: IO () processline = do putStr "prompt: " line <- getLine putStrLn ("Read: " ++ line) while :: Monad m => m Bool -> m a -> m () while t s = do b <- t if(b) then do { s; while t s; return () } else do { return () } main :: IO () main = do hSetBuffering stdout NoBuffering putStrLn "Single call:" processline putStrLn "Call from 'while' construct:" while (notM isEOF) (processline)

The problem here is that, within the `while' you are calling `isEOF' before printing the prompt. IsEOF cannot report False until you actually type the first character! If you type nothing, then it the EOF condition could indeed be true, so no more actions can happen until the condition is falsified.
processline = do putStr "prompt: " line <- getLine putStrLn ("Read: " ++ line)
while :: Monad m => m Bool -> m a -> m () while t s = do b <- t if(b) then do { s; while t s; return () } else do { return () }
main = do hSetBuffering stdout NoBuffering putStrLn "Single call:" processline putStrLn "Call from 'while' construct:" while (notM isEOF) (processline)
Regards, Malcolm

...IsEOF cannot report False until you actually type the first character...
Malcolm, Simon, and others, Thanks for the answers. I guess I've been fixated so much on trying to adapt to 'functional' programming and to actually understanding how these 'magical' Monads work that I've looked over this obvious mistake. And to think I've actally pointed this very same mistake out to loads of students in the "imperative programming" course ! (Yes,.. I'm blushing...) Thanks again, Kind regards, Alex...
participants (3)
-
Alex van Ballegooij
-
Alex van Ballegooij
-
Malcolm Wallace