Haskell

【Haskell】様々な配列その1

More than 1 year has passed since last update.

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に束縛される(妄想)。