Haskellには様々な配列があります。Array、MArray、STArray、IOArray、UArray、STUArray、IOUArray…。他にもVectorというデータ構造があり、こちらもいくつかの種類があるようで、正直どう使い分ければいいか判断がつきません。わかりやすくまとめたページを見つけることができなかったため、自分でまとめていこうと思います。といっても、いきなりすべての配列の種類を網羅した記事を書くことは困難なため、まず配列の種類毎に記事を作成し、その後ですべての配列の種類を網羅したページを作成しようと思います。途中で飽きなければいいのですが…。
通常の配列
import Data.Array
-- 配列の生成
arr1 = array (0,2) [(0,"foo"),(1,"bar"),(2,"baz")]
arr2 = listArray (1,100) [n^2|n<-[1..]]
arr3 = listArray (0,999) $ repeat False
-- 要素の取得
elem1 = arr1 ! 0 -- "foo"
elem2 = arr1 ! 2 -- "baz"
elem4 = arr1 ! 3 -- *** Exception: Ix{Integer}.index: Index (3) out of range ((0,2))
elem3 = arr1 ! (-1) -- *** Exception: Ix{Integer}.index: Index (-1) out of range ((0,2))
-- 配列の更新(更新後の配列を返す)
arr4 = arr1 // [(1,"hoge")] -- [(0,"foo"),(1,"hoge"),(2,"baz")]
arr5 = arr3 // [(2,True),(3,True),(5,True),(7,True)]
-- 配列をリストに変換
lst1 = elems arr1 -- ["foo", "bar", "baz"]
lst2 = elems arr2 -- [1, 4, 9, ..., 9604, 9801, 10000]
- 要素の追加、削除はできない。
- Haskellでは、値に変数名を紐付けることを、代入と呼ばずに__束縛__と呼ぶ。束縛した値は、まるで読み取り専用メモリ領域に書き込まれた値のように振る舞う。つまり、値の変更は許されない。
arr1
配列を更新するといっても、arr1
に束縛された(1,"bar")
という値を保持するメモリ領域が(1,"hoge")
に書き換わるわけではなく、新たにメモリ領域を確保してarr1
の値であるarray (0,2) [(0,"foo"),(1,"bar"),(2,"baz")]
を書き込み、(1,"bar")
を(1,"hoge")
に変更し終えた後で変更不可能領域となりarr4
に束縛される(妄想)。