この章では、Haskellで良く使われるリストというデータ構造を説明します。
リストは、同じタイプ (type、型) のデータを複数保持できるデータ構造です。リストに含まれる個々のデータのことを要素 (element)と呼びます。リストの各要素は、その順番によって管理されています。最初の要素の番号は0番です。
なお、リストはリストモナドというモナド型です。
リストはデータの全体を [ と ] で囲んで、各要素を , (カンマ)で区切って作ります。
a = [1, 2, 3, 4, 5]
main = do
print a
[1,2,3,4,5]
連続した値のリストを作成するのには、レンジ (range) と呼ばれる便利な書き方があります。
main = do
print [1..5]
print ['a'..'e']
print ['A'..'E']
文字は一重引用符で囲んで作ります。文字のリストは文字列になります。
[1,2,3,4,5]
"abcde"
"ABCDE"
!!
リストから要素の値を取得するには !!
を使って、何番目の要素かを指定します。要素の順番は 0 から始まっています。
a = [1, 2, 3, 4, 5]
main = do
print $ a!!3
4
リストとリストを繋ぐには ++
を使います。
main = do
print [1..5] ++ [6..10]
print "abcde" ++ "fghijk"
文字列は二重引用符で囲んで作ります。文字列は文字型 Char のリストです。
[1,2,3,4,5,6,7,8,9,10]
"abcdefghijk"
:
:
を使って、リストの先頭に要素を追加することができます。
main = do
print $ 1:[2..5]
[1,2,3,4,5]
:
を複数回使って複数の要素をリストの先頭に追加することもできます
main = do
print $ 1:2:[3..5]
[1,2,3,4,5]
:
を使ってリストの末尾に要素を追加することはできません。リストの末尾に要素を追加する際は、++
を使ってください。
関数を定義して、引数のリストから先頭の要素を取り出すことができます。
first (x:xs) = x
main = do
print $ first [1..5]
print $ first "abcdef"
1
'a'
(x:xs)
という記述で、リストの先頭がxに、残りがxsに割り当てられます。xsはxの複数形という意味です。Haskellでは慣習的にこの書き方を良く使います。
_
を使って、使わない値を無視することもできます。
first (x:_) = x
second (_:x:_) = x
main = do
print $ first [1..5]
print $ second [1..5]
1
2
リストの要素数を取得します。
main = do
print $ length [1..100]
print $ length ['a'..'z']
100
26
リストの合計を取得します。
main = do
print $ sum [1..100]
5050
リストの要素をすべて掛け合わせた値、つまり factorial (階乗)を取得します。
main = do
print $ product [1..5]
120
リストの先頭から指定した要素数のリストを取得します。
main = do
print $ take 5 [1..10]
[1,2,3,4,5]
リストの先頭から指定した要素数を取り除いたリストを取得します。
main = do
print $ drop 5 [1..10]
[6,7,8,9,10]
リストの要素を逆順にしたリストを取得します。
main = do
print $ reverse [1..10]
[10,9,8,7,6,5,4,3,2,1]
リストの中から最も大きい値を取得します。
main = do
print $ maximum [1..10]
print $ maximum ['A'..'Z']
10
'Z'
リストの中から最も小さい値を取得します。
main = do
print $ minimum [1..10]
print $ minimum ['A'..'Z']
1
'A'
リストの先頭要素を取得します。
main = do
print $ head [1..10]
1
リストの先頭要素を取り除いた、残りのリストを取得します。
main = do
print $ tail [1..10]
[2,3,4,5,6,7,8,9,10]
リストの末尾の要素を取得します。
main = do
print $ last [1..10]
10
リスの末尾の要素を取り除いた、残りのリストを取得します。
main = do
print $ init [1..10]
[1,2,3,4,5,6,7,8,9]
リストが空かどうかを取得します。
main = do
print $ null [1..10]
print $ null []
False
True
第1引数の値が第2引数のリストに含まれているかどうかを調べます。
main = do
print $ elem 1 [1..10]
print $ 'A' `elem` ['A'..'Z']
True
True
リスト内包表記とは、リストのすべての要素に同じ処理を施した別のリストを作る方法です。
main = do
print $ [x*2 | x <- [1..10]]
[2,4,6,8,10,12,14,16,18,20]
|
の右側で x
にリストの要素を1個ずつ与えます。|
の左側で、取り出した要素 x
に処理を行います。ここでは2倍にしています。, (カンマ)で区切って、リストから要素を取り出す際の条件を追加することができます。
main = do
print $ [x | x <- [1..10], mod x 2 /= 1]
[2,4,6,8,10]
Haskellの比較演算子では、等価は ==
ですが、不等価は、!=
ではなく、/=
です。