技術のメモ箱

Haskell/リスト

リストの定義

リストは要素をカンマ区切りで並べて、角括弧で括ったもの。異なる型が混じったリストは作れない。

Prelude> let numbers = [1,2,3]

文字列は文字のリストである。

Prelude> ['h','e','l','l','o']
"hello"

リストにリストを含めることができる。

Prelude> let numbers = [[1,2,3],[6,5]]
Prelude> numbers ++ [[2,2,2]]
[[1,2,3],[6,5],[2,2,2]]
Prelude> numbers !! 1
[6,5]

レンジと無限リスト

レンジを使って連番を作成できる。ステップの指定をするには、最初の2つの要素を書く。

Prelude> [1..3]
[1,2,3]
Prelude> [1, 3..9]
[1,3,5,7,9]

上限を指定しないことで無限リストを生成できる。
Haskellは遅延評価なので、必要になった分だけリストが生成される。

Prelude> take 10 [2,4..]
[2,4,6,8,10,12,14,16,18,20]

リストを生成する関数

関数説明
cycle 引数のリストを無限に繰り返し、無限リストを作る。
Prelude> take 10 (cycle [1,2,3])
[1,2,3,1,2,3,1,2,3,1]
repeat 引数の要素を無限に繰り返し、無限リストを作る。
Prelude> take 10 (repeat 5)
[5,5,5,5,5,5,5,5,5,5]
replicate リストの長さと複製する要素を指定して、リストを作る。
Prelude> replicate 3 10
[10,10,10]

リストの連結

最後に追加

++演算子は、リストの最後に追加する。リストの最後まで走査するため動作に時間がかかる。
引数は2つともリストでなければならない。

Prelude> [1,2,3] ++ [10,11,12]
[1,2,3,10,11,12]
Prelude> "hello" ++ " " ++ "world"
"hello world"

先頭に追加

:演算子(cons演算子)は、リストの先頭に追加する。一瞬でおわる。
第一引数はリストの要素の型にする。2つともリストは誤り。

Prelude> 5:[1,2,3]
[5,1,2,3]

Haskellでは[1,2,3]は1:2:3[]の糖衣構文である。[]は空のリストを表す。

リストの要素の取得

指定位置の取得

!!演算子を使って、要素を先頭からの位置で指定して取得する。添字は0から。

Prelude> let numbers = [1,2,4]
Prelude> numbers !! 1
2

要素数の取得

length関数はリストの長さを返す。

Prelude> length [5,4,3,2,1]
5

要素の取得

関数説明
head 先頭の要素を取得する。
Prelude> head [5,4,3,2,1]
5
tail 先頭の要素を除いた残りのリストを取得する。
Prelude> tail [5,4,3,2,1]
[4,3,2,1]
last 最後の要素を取得する。
Prelude> last [5,4,3,2,1]
1
init 最後の要素を除いた残りのリストを取得する。
Prelude> init [5,4,3,2,1]
[5,4,3,2]

リストの操作

新しいリストを作る

関数説明
revers リストを逆順にする。
Prelude> reverse [5,4,3,2,1]
[1,2,3,4,5]
take 先頭から指定された数の要素を取得する。
Prelude> take 3 [5,4,3,2,1]
[5,4,3]
drop 先頭から指定された数の要素を削除する。
Prelude> drop 3 [5,4,3,2,1]
[2,1]

リストを調べる

関数説明
null リストが空かどうか調べる。
Prelude> null []
True
elem リストに指定した要素が含まれているか調べる。中置関数として使うと読みやすい。
Prelude> 4 `elem` [3,4,5,6]
True

集計する

関数説明
maximum 最大の要素を返す。
Prelude> maximum [1,9,2,3,4]
9
minimum 最小の要素を返す。
Prelude> minimum [8,4,2,1,5]
1
sum 数のリストを受け取り、それらの和を返す。
Prelude> sum [5,2,1,6]
14
product 数のリストを受け取り、それらの積を返す。
Prelude> product [5,2,1,6]
60

リストの比較

中の要素が比較可能であればリストも比較可能である。
2つのリストの先頭の要素から比較し、等しければ2番目の要素同士が比較される。

Prelude> [3,2,1] > [2,1,0]
True

また、空でないリストは空のリストよりも大きいとみなされる。

Prelude> [2,2,0] > [2,2]
True

リスト内包表記

数学における集合の内包的記法に近いものが書ける。
例えば、{2・x | x∈N, x≦10}をリスト内包表記で書くと以下となる。

Prelude> [x * 2 | x <- [1..10]]
[2,4,6,8,10,12,14,16,18,20]

カンマで区切れば、内包表記に条件を追加できる。

Prelude> [x * 2 | x <- [1..10], x * 2 >= 12]
[12,14,16,18,20]

複数のリストを扱うこともできる。(つまり多重ループ)

Prelude> [(x,y) | x <- [1,2,3], y <- [4,5,6]]
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]

mapt関数とfilter関数を使っても同じことができる。分かりやすさで使い分ける。

pagetop