Skip to content

Instantly share code, notes, and snippets.

@nabeken
Last active December 10, 2015 21:59
Show Gist options
  • Select an option

  • Save nabeken/4499259 to your computer and use it in GitHub Desktop.

Select an option

Save nabeken/4499259 to your computer and use it in GitHub Desktop.
初haskellなのでこんな感じで…
{--
- catコマンドみたいに動く。
- コマンドライン引数を取り、引数が空なら標準入力をそのまま出力する
- それ以外なら引数をファイル名と解釈し、中身をそのまま出力する
-}
import System.IO
import System.Environment
import Control.Applicative
import Control.Monad
import Control.Exception
-- http://d.hatena.ne.jp/kazu-yamamoto/20120605/1338871044
ioHandler :: IOException -> IO String
ioHandler e = do
hPutStr stderr $ show e ++ "\n"
return ""
cat :: [FilePath] -> IO String
cat [] = do getContents
cat files = do concat <$> forM files (\f -> handle ioHandler $ readFile f)
main = getArgs >>= cat >>= putStr
@nabeken
Copy link
Author

nabeken commented Jan 11, 2013

アプリカティブスタイルで書いてみた。一々 <- しているのがちょっと気になっている。

@nabeken
Copy link
Author

nabeken commented Jan 11, 2013

本物のcatコマンドは複数のファイル名が与えられた時、ファイルが存在していない場合はそのファイルのみを無視し、継続するようになっている。

cat.hsでは1つでもファイルが存在していないとcatされないことに気がついた。エラーがあった場合はメッセージを出して継続させてみる。

@nabeken
Copy link
Author

nabeken commented Jan 21, 2013

>>= を使うと do記法で <- でいちいち束縛する必要がなくなった。しかし、この記法ではエラー処理を入れるのが面倒か?

@nabeken
Copy link
Author

nabeken commented Jan 21, 2013

Control.Exceptionのhandleを使ってIOExceptionを捕捉するようにしてみた。これでcatの動作に近い。

エラーメッセージは標準エラー出力に出したい…

@nabeken
Copy link
Author

nabeken commented Jan 21, 2013

できた。次は -n で行数を出してみたい。

@nabeken
Copy link
Author

nabeken commented Jan 21, 2013

本物のcatはエラーメッセージは都度表示される。この実装だとreadFile時にエラーがすべて拾われてしまうので、エラーメッセージが最初に固まって表示される。 concat 時に拾えばいいんかな。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment