"interact" behaves oddly if used interactively
Hi, For GHC (6.0.1) "main=interact id" basically echoes every line of my input, whereas "main=interact show" correctly waits for EOF before outputting something. Furthermore the buffering mode must be "LineBuffering". If I explicitely set the buffering to "NoBuffering" I'm not able to enter EOF by typing "ctrl-d". Furthermore my terminal seems to remain in the buffering mode set by the previously called ghc-haskell program (because it effects programs that do not "hSetBuffering".) With "runhugs" (Nov 2002) there is no premature output for "interact id", the buffering mode does not matter, but "ctrl-d" is not recognized as EOF. NHC98 does not even wait for a line break before outputting the result (and echoes "\EOT" for "ctrl-d"). What should a student think about "interact" in the Prelude? (It's ok for pipes only, I guess.) Christian module Main where import System.IO main = do hSetBuffering stdin NoBuffering interact id -- maeder@turing:~/haskell/examples> bash --version GNU bash, version 2.05b.0(1)-release (i586-suse-linux) Copyright (C) 2002 Free Software Foundation, Inc. maeder@turing:~/haskell/examples> ghc --version The Glorious Glasgow Haskell Compilation System, version 6.0.1 maeder@turing:~/haskell/examples> ghc --make Interact.hs -o interact Chasing modules from: Interact.hs Compiling Main ( Interact.hs, ./Interact.o ) Linking ... maeder@turing:~/haskell/examples> ./interact 1 1 2 2 3 3 ^D^D^D ccc interact: interrupted
On Tue, Sep 30, 2003 at 03:52:50PM +0200, Christian Maeder wrote:
Hi,
For GHC (6.0.1)
"main=interact id" basically echoes every line of my input, whereas "main=interact show" correctly waits for EOF before outputting something.
That's only because output to terminal is line buffered by default and show converts all newlines to \n. Try feeding it from /dev/urandom or similar endless character resource - you'll see that it doesn't wait for EOF. PS. The name 'interact' suggests interaction :) Best regards, Tom -- .signature: Too many levels of symbolic links
"main=interact id" basically echoes every line of my input, whereas "main=interact show" correctly waits for EOF before outputting something.
What should a student think about "interact" in the Prelude? (It's ok for pipes only, I guess.)
main = interact show behaves similar to main = interact (\x->seq (length x) x) i do not know the exact implementation, but i think of it like ... import System.IO (hGetContents,hIsEOF,hGetChar,stdin) import System.IO.Unsafe (unsafePerformIO) interact :: (String -> String) -> IO () interact f = do s <- hGetContents stdin putStr $ f s putStr = mapM_ putChar hGetContents h = do eof <- hIsEOF h if eof then return [] else c <- hGetChar h return (c : (unsafePerformIO $ hGetContents h)) ... so there will be the same problems like with getChar, hGetChar, getLine, or hGetLine (buffering), and with hGetContents and unsafePerformIO (sequrence of IOs). for beginners/students: think about such situations: (to me, it was the reason to learn IO monadic programming) read the next char(s) from input before writing the previous char(s) to output. f :: String -> String f [] = [] f (c:[]) = (c:[]) f (c:s) = (c:f s) equals to f :: String -> String f [] = [] f (c:[]) = (c:[]) f (prev:s@(next:_)) = (prev:f s)
participants (3)
-
Christian Maeder -
Marc A. Ziegert -
Tomasz Zielonka