
Here's an alternative: module Main where import System.IO import System(getArgs) catFile :: FilePath -> IO () catFile fp = do contents <- readFile fp putStr contents main :: IO () main = do hSetBuffering stdin (BlockBuffering Nothing) args <- getArgs if not (null args) then mapM_ catFile args else do contents <- getContents putStr contents This avoids the whole EOF problem by using lazy I/O. readFile and getContents both return a String, but it's a lazy list; the contents of the string are only generated on demand. So this does not actually read the entire file into memory as you might think at first glance. Also, I added a hSetBuffering line. Setting it to BlockBuffering can improve performance. LineBuffering could also be useful if people are used to a certain type of interactive performance with cat. -- John