
Hi Sean, I'm not expert, but since you asked for idiomatic comments, here are a few... On 18 Feb 2005, at 09:58, Sean Perry wrote:
Also, while talking about untilEOF, it is slightly annoying that hIsEOF returns IO Bool and that functions like 'not' only want Bool. Sure makes the logic tests feel like more work than they should be.
`Annoying' in some sense, but it could hardly be any other way. You can always lift 'not' into the IO monad, as in (liftM not).hIsEOF
untilEOF :: Handle -> (Handle -> IO ()) -> IO () untilEOF hdl f = do eof <- hIsEOF hdl if eof then return () else do f hdl untilEOF hdl f
This idiom with if .. then return () else ... is the 'unless' idiom from Control.Monad: untilEOF hdl f = do eof <- hIsEOF hdl unless eof $ do f hdl untilEOF hdl f there is also 'when' for the opposite. Here is an example just to demonstrate how to lift 'not' should you ever want to: untilEOF' hdl f = do eof <- (liftM not)(hIsEOF hdl) when eof $ do f hdl untilEOF' hdl f
cat :: Handle -> IO () cat hdl = do line <- hGetLine hdl putStrLn line
arguably more idiomatic is: cat hdl = hGetLine hdl >>= putStrLn
main :: IO () main = do args <- getArgs if (length args) > 0 then mapM_ catFile args else untilEOF stdin cat
if (not null args) is preferred to if (length args) > 0 as a general principle (it's faster for long lists). Jules