[Haskell-cafe] new Haskell hacker seeking peer review

Jules Bean jules at jellybean.co.uk
Fri Feb 18 07:41:29 EST 2005


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



More information about the Haskell-Cafe mailing list