2015-12-13 『ふつうのHaskellプログラミング』 もくもく読書会(第2章) の振り返り
ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門
- 作者: 青木峰郎,山下伸夫
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/06/01
- メディア: 単行本
- 購入: 25人 クリック: 314回
- この商品を含むブログ (320件) を見る
第2章 Haskellの基礎(1) 関数とリスト
Hello, World!! の文法
- 識別子は大文字と小文字が区別される
main = putStrLn "Hello, World!"
main
は変数putStrLn "Hello, World!
は値- 値は関数ではなくaction(actionについては第11章で説明)
Haskellではプログラムを開始するとmainアクションの評価から処理が開始される
"Hello, World"
はputStrLn
関数の引数- 引数を例のように括弧でくくらないで空白の後に置く → 括弧でくくることも可能
Haskellでは引数を渡して関数を呼び出すことを「引数に関数を適用(apply)する」という
疑問点
関数とアクションの定義の違いがいまいちわからない
→ 11章で説明されるのか?
cat.hs
- 入力された内容をそのまま標準出力する
- 事前にソースファイルと同じフォルダにUSA-states.txtが必要
ソースの内容
- getContentsアクションは「標準入力を読み込むという契約」
- 変数csに束縛されているのはgetContentsアクション
- putStr関数で変数csを参照した時に初めてgetContentsアクションが活性化されテキストを読み込み文字列を返す
WindowsならCtrl+Z+Enterで終了とあるが同時押しではなくCtrl+Zは同時に押した後にEnter。 Ctrl+Cでいきなり終了させることも可能。
getContents
- 標準入力を全て読み込むアクション
putStr関数
- 改行なしの引数の文字列を出力する関数
- ここではファイル内に改行があるので関数での改行は不要
do式
do 構文1
構文2
構文3
・・・
- 複数の式を束ねる構文
- 構文ごとのインデントをそろえないといけない
- do式でまとめるとアクションが上から下に実行される(構文1 → 構文2 → 構文3・・・)
- do式でまとめないと上から下に実行されるか保証されない → 遅延評価のため
<-
- アクションの結果を得るときに使う構文:
変数名 <- アクション
- 変数と値を結び付けることを「変数を値に束縛(bind)する」と言う
- 右辺にはアクションなどの限られた型の値にしか使えない
- do式など限られた所でしか使えない
countline.hs
標準入力の行数を数える
リスト
- 同じ型の値を一列に並べたデータ構造(一方行リンクリストと同じ)
- 末尾は空リスト
- Haskellでは文字列は文字のリスト(文字列は存在しない)
書式
[ 値1,値2 ,値3・・・ ]
「$」演算子
- 二項演算子
- 演算をする目的よりも式を区切るために使われる
print $ length $ line cs
↓
print $length (line cs)
↓
print (length (line cs))
lines関数
- 文字列を行ごとのリストにする関数
- 改行文字は取り除かれる
"aaa bbb ccc"
↓ リストになる
["aaa", "bbb", "ccc"]
疑問点
- lines関数の改行文字はCR+LFでもLFでも区別できるのか?
→ できるもよう。 下記を作成し改行LFのテキストと改行CR+LFのテキストを読み込ませたが結果は正しくリストになっていた
main = do cs <- getContents print $ lines cs
※ Windows環境で実施
head.hs
- 標準出力の最初の10行のみ取得する
firstNLines関数を定義する
- 対象文字列を第1引数の行数分だけ取得する関数
- 引数が2つある
引数が2つある場合は空白で区切って指定することが可能
firstNLines 行数 対象文字列
unlines関数
- 文字列のリストを連結して行つきの文字列にする関数
- lines関数の逆
take関数
- リストの先頭からn要素をとってリストで返す関数
- リストが指定されたnより少ない場合はリスト全体を返す
> take 3 [1, 2, 3, 4, 5] [1, 2, 3]
tail.hs
- 入力の最後の10行を表示する
- headとは逆
reverse関数
- リストを逆順にする
> reverse [1, 2, 3] [3, 2, 1]
練習問題
答え1
本の解答は下記
main = do cs <- getContents print $ length cs
- 問題文にはバイト数とあるが日本語入力は対象外のもよう。(日本語はエラーになる)
countline
として入力するのではなくcountline < ファイル名
でテキストファイルを読み込んでそのバイト数を返す
→ テキストを指定していないと入力後にEnterかCtrl+Cなどが含まれるのか変な値が出力される- テキストファイルに改行を含んでいるともちろん1文字と数える
答え2
本の解答は下記
main = do cs <- getContents print $ length $ words cs
これは特に問題なし。改行で区切ったのも問題なかった。