[Haskell-cafe] How to write elegant Haskell programms? (long posting)

David Roundy droundy at darcs.net
Mon Jan 29 20:32:44 EST 2007


On Mon, Jan 29, 2007 at 05:30:41PM -0600, Eric Mertens wrote:
> import Control.Monad (liftM, forM_)
> import Directory (getModificationTime, renameFile)
> import Text.Printf (printf)
> import System.FilePath ((</>),(<.>))
> import System.Locale (defaultTimeLocale)
> import System.Path.Glob (glob)
> import System.Time (toUTCTime, formatCalendarTime, getClockTime, ClockTime)
> 
> basenames = ["mail.log", "thttpd.log" ]
> logdir    = "/var/log"
> 
> main =
>  forM_ basenames $ \ basename -> do

Interesting, I've never used forM_! It's just flip mapM_, but that's pretty
convenient...

>    oldnames <- glob (logdir </> basename <.> "*.gz")
>    forM_ oldnames $ \ oldname -> do
>      now <- timestamp oldname
>      let newname = logdir </> "archive" </> basename <.> now <.> "gz"
>      printf "mv %s %s" oldname newname

Surely it'd be more idiomatic to just use

       putStrLn $ unwords ["mv", oldname, newname]

or

       putStrLn $ "mv " ++ oldname ++ " " ++ newname

(which also prints a newline, but I imagine that's what's actually wanted)

>      renameFile oldname newname
> 
> timestamp path = do
>  t <- getModificationTime path
>  return $ formatCalendarTime defaultTimeLocale "%Y%m%d" $ toUTCTime t

Surely this would be nicer as:

timestamp path = (formatCalendarTime defaultTimeLocale "%Y%m%d" . toUTCTime)
                 `liftM` getModificationTime path

(although I prefer using fmap instead of liftM)
-- 
David Roundy
Department of Physics
Oregon State University


More information about the Haskell-Cafe mailing list