
On 2004-09-28 at 21:19-0000 John Goerzen wrote:
On 2004-09-28, Peter Simons
wrote: John Goerzen writes: FWIW, this is working for me:
import IO
main = disp 100
disp 0 = return () disp n = let copy x = do eof <- isEOF if eof then return () else do line <- getLine putStrLn line (copy 0) in do copy 0 hSeek stdin AbsoluteSeek 0 disp (n-1)
but it seems wasteful to poll isEOF so much.
Why do you say that? The condition has to be tested for, whether you do it by polling or waiting for an error to be thrown For my 2¢, I think I prefere this sort of thing to look like this:
import IO
number_of_copies = 100
main = mapM_ contentsToStdOut $ replicate number_of_copies stdin
contentsToStdOut hdl = do line_by_line hdl hSeek hdl AbsoluteSeek 0
line_by_line hdl = foldIO (const putStrLn) () hGetLine hdl
foldIO process_item initial_state io_operation handle = process initial_state where process state = do eof <- hIsEOF handle if eof then return state else do item <- io_operation handle new_item <- process_item state item process $ new_item
and some version of foldIO should probably be in a library somewhere. If you really don't like polling, you can write this:
contentsToStdOut hdl = do t <- try $ line_by_line hdl hSeek hdl AbsoluteSeek 0 case t of Right () -> error "this never happens" Left e -> if isEOFError e then return () else ioError e
with
line_by_line hdl = do line <- hGetLine hdl putStrLn line line_by_line hdl
Note that all of these are incorrect because hGetLine doesn't tell you whether there was a newline at the end of file. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk