Concurrent Clean : メモリアロケートの遅延

自明といえばそうなのですが、遅延評価を利用すると、大きな配列のメモリアロケートを遅延することができたりします。
次のプログラムは、STというレコードを要素に持つ要素数10000の配列を作成し、その26番目と257番目の要素だけを取得するというプログラムです。各要素がメモリアロケートされたことを見るために、レコードのコンストラクタにtrace関数を仕掛けてあります。

Start = let ar = mkarr 5 in  (ar.[25], ar.[256])

::ST = {a::!Int, b::Int}

mkarr :: Int -> {ST}
mkarr n = {{a=trace (toString x) x,b=n} \\ x <- [0..9999]}

普通の言語だと、配列が初期化されたところで、全ての要素がメモリアロケートされて、0..9999のtrace出力が画面に表示されるところですが、Cleanでの実行結果はこうなります。

(25(ST 25 5),256(ST 256 5))

まあ、あたりまえですが、リストだけではなくて配列でもこういう効果が期待できるということは、配列を使ったプログラムの書き方を工夫できます。