RubyのARGFっぽい何か

RubyのARGFって何気に便利でよく使ってました。Haskellでも同じようなことできないかなと思って、こんな関数を書いてみました。

readFiles :: [String] -> IO String
readFiles [] = getContents
readFiles files = do
  ss <- mapM readFile files
  return $ concat ss

引数にファイル名のリストを渡すと、そのファイルの内容を読み込んでひとつのIO Stringとして返します。引数が空の場合には、標準入力の内容を読み込んで、その内容をIO Stringとして返します。
これを使ってcatコマンドを実装すると以下のようになります。おお、main関数が綺麗です。
ファイル: cat2.hs

module Main (main) where

import System.Environment (getArgs)

main :: IO ()
main = putStr =<< readFiles =<< getArgs

readFiles :: [String] -> IO String
readFiles [] = getContents
readFiles files = do
  ss <- mapM readFile files
  return $ concat ss

ファイル: Makefile

TARGET  = cat2
SOURCES = cat2.hs

HC      = ghc
HCFLAGS = -W -fno-warn-unused-matches --make

all: $(TARGET)

$(TARGET): $(SOURCES)
	$(HC) $(HCFLAGS) $< -o $@

clean:
	rm -f $(TARGET) *.o *.hi *.exe