関数プログラミングのアプローチ (28)

破壊的に配列を操作する

前回は、関数プログラミングにおける配列の取り扱いの問題について、代替となる関数的なデータ構造を用いる方法について説明しました。それに対し、今回は配列を直接破壊的に操作するアプローチについて説明します。
配列の操作に関しても、入出力と同じように、一意型やモナドを用いたアプローチが有効です。ここでは、一意型を用いたアプローチを紹介します。一意型システムは第18回第20回の実装を用います。

def select (arr, idx):
    _arr = fromUnique(arr)
    res = _arr[idx]
    return res, Unique(_arr)

def update (arr, idx, elm):
    _arr = fromUnique(arr)
    _arr[idx] = elm
    return Unique(_arr)

これを用いると、前々回のプログラムは次のように表現することができます。

def func (ls): return select(ls, 1)

ls = Unique([1,2,3])
a, ls = func(ls) // -- (1)
ls = update(ls, 1, 10)
b, ls = func(ls) // -- (2)

このプログラムは、配列を破壊的に更新するので効率的で、なおかつ、配列の操作に一意型を用いているため関数的です。
ここで注目するところは、配列の選択も特別な関数(select)を用いているところです。ちょっと考えるとこれは不要に思うかもしれません。しかし、配列の要素を選択する場合、配列のいつの時点の値にアクセスしようとしているのかが確定しなければ、正しい値を得ることはできないため、この関数が必要になります。