1. Prelude の意味
Haskell のコードを読めるようになるためには、基本となる Prelude を押さえる必要がある。ところで、Prelude の意味は、
1 (出来事などの)前ぶれ, 前兆((to ...))
2 (…の)準備行為, 前口上((to ...))
3 《楽》前奏曲, プレリュード.(Yahoo!辞書 – prelude より)
Prelude は、Haskell のコードを書けば自動的に import される。自分の実行したいコードの前に奏でられる「前奏曲」と覚えておけばいいのかな。
Prelude is a module that contains a small set of standard definitions and is included automatically into all Haskell modules.
ちなみに、前奏曲 - Wikipedia とは、
(他の楽曲の・大規模な楽曲の)前に演奏する楽曲の意味である。
2. Prelude の区分
Prelude が、どのような構成になっているか、見てみると、
- 基本的な型、クラスと、それに関連した関数
- リスト操作
- 文字列の変換
- 基本的な入出力
2 番目の「リスト操作」については、これまでに関数をいくつか試した。
- リストの n 番目の要素を取得 – PreludeList の !! : !! とその他基本的なリスト操作
- foldl , foldr
- リストの要素を join - List.Data の intersperse, intercalate
- 簡単なテキスト処理 - データの抽出 : filter
Prelude を構成するモジュール
The Haskell 98 Report: Standard Prelude によると、
プレリュードはひとつのルートモジュール Prelude と 3つのサブモジュール PreludeList、PreludeText お よび PreludeIO で組織されている。
よって、先ほど列挙した Prelude の構成の項目は、以下と対応している。
- ルートモジュール
- PreludeList
- PreludeText
- PreludeIO
3. リスト操作の基本
最初に、リストの基本的な操作 を、自分なりに分類しておく。
- 基本
- 要素の取得
- 各々の要素に対する処理
- 逆順
4. リスト操作の分類
Prelude にある、リストに対する、基本的な操作以外の分類を見てみる。
- 要素の重ね合わせ (要素をまとめる) : fold, 特殊なタイプ
- 生成 : scan (fold のリスト版)、繰り返し
- 部分 : take, drop
- 検索 : elem, lookup
- リスト同士のすりあわせ : zip
- 文字列と文字列のリスト : lines, words
今回は、 1 番目の「要素の重ねあわせ」について、試してみる。
5. リスト要素の重ね合わせ
「リストの要素の重ね合わせ」とは、リストから要素を取り出し、関数 f を適用しながら、要素を重ね合せていくイメージ。リストの内容を、一つの要素にまとめていく機能を持つ。
具体的には、「リストの要素を合計する操作」などを思い浮かべるのがよい。
Haskell では、これに対応する関数名は foldl , foldr 。
追記 (2011.11.30) : この記事を書いたときに、意識してなかったことは、以下を参照。
操作の種類と例
リストの要素を、先頭(左)から重ねあわせていく方法と、末尾(右)から重ね合わせる方法の 2 つが定義されている。
先ほどの図中において、ピンク色がついている要素が「初期値」を表わすと考える。
初期値のないものが、それぞれ `foldl1, foldr1’ 。
foldl : 左から重ねる
main = do print $ foldl (\x y -> x + y) 0 [1,2,3,4,5] -- 15 print $ foldl (+) 0 [1,2,3,4,5] -- 15 print $ foldl (-) 10 [1,2,3,4,5] -- -5
foldr : 右から重ねる
main = do -- 1-10 print $ foldr (-) 10 [1] -- -9 -- 1-(2-10)) print $ foldr (-) 10 [1,2] -- 9 -- 1-(2-(3-(4-(5-10)))) print $ foldr (-) 10 [1,2,3,4,5] -- -7
foldl1, foldr1 : 初期値なし
main = do print $ foldl1 (+) [1,2,3,4,5] -- 15 -- 1-(2-(3-(4-5))) print $ foldr1 (-) [1,2,3,4,5] -- 3
6. 特殊な重ね合わせ
上記の「重ね合わせ・まとめあげ」をする関数から導かれる、特殊な関数。
sum, product, maximum, minimum : 総和、総乗、最大、最小
main = do print $ sum [1,2,3,4,5] -- 15 print $ product [1,2,3,4,5] -- 120 print $ maximum [1,2,3,4,5] -- 5 print $ minimum [1,2,3,4,5] -- 1
any, all : 要素の存否
main = do print $ any (==3) [1,2,3,4,5] -- True print $ any (>3) [1,2,3,4,5] -- True print $ any (\x -> x > 30) [1,2,3,4,5] -- False print $ all (>=1) [1,2,3,4,5] -- True
一つ括弧をはずす : concat, concatMap
concatMap は、map して concat
main = do print $ concat [[1,2,3],[4,5,6],[7,8,9]] -- [1,2,3,4,5,6,7,8,9] print $ concat [[[1,2]],[[3,4]],[[5,6]]] -- [[1,2],[3,4],[5,6]] print $ concat ["hoge", "piyo"] -- "hogepiyo" print $ map (:['!']) ['a','b','c'] -- ["a!","b!","c!"] print $ concatMap (:['!']) ['a','b','c'] -- "a!b!c!" print $ map ('*':) ["hoge", "piyo"] -- ["*hoge","*piyo"] print $ concatMap ('*':) ["hoge", "piyo"] -- "*hoge*piyo"
and, or は何にどう使えばいいだろう?(@_@) QQQ
main = do print $ and [True, False, True] -- False print $ and [True, True, True] -- True print $ and $ map (>3) [4,5,6] -- True print $ and $ map (>3) [3,4,5,6] -- False print $ or $ [x>3 | x <- [4,5,6]] -- True print $ or $ [x>3 | x <- [1,2,3]] – False
0コメント:
コメントを投稿