(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Haskell入門】リストの操作

スポンサーリンク

Haskellでは[ ]にて同種のデータを配列のように保持することができます。
リストの考え方やよく使う関数等を整理しました。ghciで対話式にコマンドを押下していきます。

以下、目次です。

同種のデータしか入れられない

Prelude> [1,2]
[1,2]
Prelude> [1,"2"]
<interactive>:X:X:
    No instance for (Num [Char]) arising from the literal `1'
    Possible fix: add an instance declaration for (Num [Char])
    In the expression: 1
    In the expression: [1, "2"]
    In an equation for `it': it = [1, "2"]

数値と文字列を入れるとエラーとなります。

文字列は文字のリスト

シングルクォーテーションで区切った文字のリストは以下のように文字列となります。

Prelude> "Hello"
"Hello"
Prelude> ['H','e','l','l','o']
"Hello"

言い換えれば文字列は文字のリストと考えることができます。

ちなみに文字は2文字以上入れることはできません。

Prelude> ['a','b']
"ab"
Prelude> ['a','bc']
<interactive>:X:X:
    Syntax error on 'bc'
    Perhaps you intended to use -XTemplateHaskell

リストの連結は++

++を利用することで最下部に値が追加できます。

Prelude> [1,2,3] ++ [4,5]
[1,2,3,4,5]
Prelude> ["1","2","3"] ++ ["4","5"]
["1","2","3","4","5"]

文字の連結は以下のようになるため

Prelude> ['H','e']++['l','l','o']
"Hello"

文字列はリスト形式にせずとも連結が可能です。

Prelude> "He" ++ "llo"
"Hello"

数値ではできません。

Prelude> 1 ++ 2
<interactive>:X:X:
    No instance for (Num [a0]) arising from the literal `1'
    Possible fix: add an instance declaration for (Num [a0])
    In the first argument of `(++)', namely `1'
    In the expression: 1 ++ 2
    In an equation for `it': it = 1 ++ 2

先頭に追加は :

以下のように:を用いればリストの先頭に追加可能です。

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

複数の追加も可能です。

Prelude> -1:0:[1,2,3]
[-1,0,1,2,3]

要素の抜粋は !! NUM

要素は0から始まります。

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

もちろん範囲を超えるとエラーになります。

Prelude> [1,2,3] !! 3
*** Exception: Prelude.(!!): index too large

リストの中にリストを入れ込む

Prelude> [[1,2,3,4],[5,6,7,8],[9,10]] 
[[1,2,3,4],[5,6,7,8],[9,10]]

Prelude> [[[1,2],[3,4]],[[5,6],[7,8,9]]]
[[[1,2],[3,4]],[[5,6],[7,8,9]]]

といったリストの中にリストを入れ込むこともできます。

込み入っていますが、!!を利用して値を確認すれば全容が分かりやすくなります。

Prelude> [[[1,2],[3,4]],[[5,6],[7,8,9]]] !! 1
[[5,6],[7,8,9]]
Prelude> [[[1,2],[3,4]],[[5,6],[7,8,9]]] !! 1 !! 1
[7,8,9]
Prelude> [[[1,2],[3,4]],[[5,6],[7,8,9]]] !! 1 !! 1 !! 1
8

比較は先頭から

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

文字列も同様です。

Prelude> ["d","c","b"] > ["a","b","c"]  
True
Prelude> ["a","c","b"] > ["a","b","c"]  
True
Prelude> ["a","a","b"] > ["a","b","c"]  
False

head/init/tail/last/take/dropでリスト抽出

headlastが先頭と末端、inittailが末端以外と先頭以外です。

Prelude> ["H","el","lo","World"]
["H","el","lo","World"]
Prelude> head ["H","el","lo","World"]
"H"
Prelude> init ["H","el","lo","World"]
["H","el","lo"]
Prelude> tail ["H","el","lo","World"]
["el","lo","World"]
Prelude> last ["H","el","lo","World"]
"World"

take NUMにて先頭から指定した数値の要素で取り出すことができます。

Prelude> take 2 ["H","el","lo","World"]
["H","el"]
Prelude> take 3 ["H","el","lo","World"]
["H","el","lo"]

反対側から取り出す場合はdrop NUMです。指定した数値の要素を先頭から取り除きます。

Prelude> drop 2 ["H","el","lo","World"]
["lo","World"]
Prelude> drop 3 ["H","el","lo","World"]
["World"]


このあたりを使えれば、一先ずはリストの操作ができると思います。
以上、備忘録でした。