Hatena::Grouphaskell

lnzntのHaskell日記 このページをアンテナに追加 RSSフィード

2014年11月23日(日)

コマンドライン引数を表示するプログラム

| 06:07 |  コマンドライン引数を表示するプログラム - lnzntのHaskell日記 を含むブックマーク はてなブックマーク -  コマンドライン引数を表示するプログラム - lnzntのHaskell日記  コマンドライン引数を表示するプログラム - lnzntのHaskell日記 のブックマークコメント

久々に Haskell の勉強。備忘録。

import System.Environment (getArgs)

main = print =<< getArgs

参考にした書籍では System.getArgs になっていたが、現在は System.Environment.getArgs のようだ。

上のプログラムは以下と等価。

import System.Environment (getArgs)

main = do cs <- getArgs
          print cs

getArgs はモジュール system.Environment に属するアクション

Haskell の関数は参照透明性を持ち副作用がないが、アクションは副作用を扱う。

アクションの結果を取り出し変数(上ではcs)を束縛するのが「<-」。do の中でしか使えないらしい。

アクションの結果を一時変数なしに直接参照(?)するのが「=<<」のようだ。

モジュール

モジュールは「import」によりインポートして使う。

インポートしたモジュールでエクスポートされている関数やアクションなどが使える。

特定のアクション等のみをインポートする場合は上の「(getArgs)」のように指定する。

標準入力からの入力をそのまま出力するプログラムは以下。(cat もどき)

import System.IO (getContents)

main = putStr =<< getContents

「>>=」を使って書き換えると以下。(「>>=」は bind と呼ばれる)

main = getContents >>= putStr

tac もどき

Linuxtac は入力を行単位の逆順に出力するコマンドである。(多分 cat の反対なので tac)

tac もどきのプログラムは以下のようになる。

import System.IO (getContents)

main = putStr . unlines . reverse . lines =<< getContents

「.」は関数を合成する。

Ruby で以下のように書かれているのとだいだい同じ。

puts $<.readlines.reverse.join

関数合成Ruby のメッソドチェーンと対比して考えると、自分的には、理解しやすい。

rev もどき

Linux の rev は入力の各行を逆に並びかえたものを出力するコマンドである。

rev もどきのプログラムは以下のようになる。

import System.IO (getContents)

main = putStr . unlines . map reverse . lines =<< getContents

「.」での関数合成は、引数を一つとる関数しか合成できないらしい。

「map reverse」は部分適用によって引数を一つとる関数に変換されている(と思う)。

Ruby で書くとこうなる。

puts $<.readlines.map(&:reverse).join

Ruby 版は最初の行の改行文字も出力されるので、出力が若干異なる。(ま、いいか)