1 line simple cat in Haskell

William Lee Irwin III wli@holomorphy.com
Wed, 13 Nov 2002 19:43:25 -0800


On Wed, 13 Nov 2002, William Lee Irwin III wrote:
>> main = mapM_ (\h -> mapM_ putChar =<< hGetContents h) =<< mapM (flip openFile $ ReadMode) =<< getArgs

On Wed, Nov 13, 2002 at 07:46:41AM -0800, Hal Daume III wrote:
>   main = interact id

There is a semantic difference here, as the version I posted above takes
files from the command-line, though it does fail to accommodate the
pass-through case, which is handled by:

main = getArgs >>= \args ->if args == [] then interact id else mapM readFile args >>= mapM_ putStr

.. which seems to be a bit above 80 chars. Some library function trickery
is probably in order to cut the if statement down to size. e.g.

nonEmptyMapM_ :: Monad m => m () -> (t -> m ()) -> [t] -> m ()
nonEmptyMapM_ def _ []       = def
nonEmptyMapM_ _   f xs@(_:_) = mapM_ f xs
main = getArgs >>= nonEmptyMapM_ (interact id) ((>>= putStr) . readFile)

Bill