runghc -eを直したので以下でいける。

$ runghc -e 'import System;main=getArgs>>=mapM_ catFile;catFile a=do{c<-readFile a;mapM_ putStrLn $ zipWith (\x y->(reverse$take 4$reverse("    "++(show x)))++" "++y) [1..] (lines c)}' a.txt
   1 aaa
   2 bbb
   3 

以下は直す前。

早速、functionで定義したrunghc -e の引数の扱いではまってしまった。
"____"のところをスペースにするとはまる。
もちろん別ファイルで組めばOK

$ runghc -e 'import System;main=getArgs>>=mapM_ catFile;catFile a=do{c<-readFile a;mapM_ putStrLn $ zipWith (\x y->(reverse$take 4$reverse("____"++(show x)))++" "++y) [1..] (lines c)}' a.txt
___1 aaa
___2 bbb
___3 

うーん、replicate 4 ' 'でやろうとおもったが''はコマンドライン上で使えないし。replicate 4$head " "で代行(笑)

$ runghc -e 'import System;main=getArgs>>=mapM_ catFile;catFile a=do{c<-readFile a;mapM_ putStrLn $ zipWith (\x y->(reverse$take 4$reverse$(replicate 4$head " ")++(show x))++" "++y) [1..] (lines c)}' a.txt
   1 aaa
   2 bbb
   3 

うーん、何度もmapM_を使うのが嫌になったのでzip3で挑戦。

$ runghc -e 'import System;main=getArgs>>=mapM_ catFile;catFile a=do{c<-readFile a;putStrLn$concat$zipWith3(\x y z->(reverse$take 4$reverse$(replicate 4$head " ")++(show x))++" "++y++z)[1..](lines c)(repeat"\n")}' a.txt
   1 aaa
   2 bbb
   3 

IOモナドで順序制御(?)しているところが気持ち悪い。
まあ、答えの文字列を作って一挙に出力するところは気に入った。
どうもrubyの癖で書いてしまうため、カーソル移動が頻繁になってしまうのが難点だな。