Concurrent Clean : 配列パターンの落とし穴

[id:lethevert:20061105:p2]で紹介した配列パターンだが、思わぬ落とし穴が。

get_or_zero i arr # (l,arr) = usize arr
                  = f l i arr
  where
    f l i arr=:{[i]=ai} | i>=l = (0,arr)
                               = (ai,arr)

とか、遅延評価を期待して書いてやると、aiのところが遅延評価されないで index out of range になってしまう。
つまり、次のように解釈されてしまうということだ。

    f l i arr # (ai,arr) = arr![i]
              | i>=l = (0,arr)
                     = (ai,arr)

なので、ここでは、次のように明示的に書かなければいけない。

    f l i arr | i>=l = (0,arr)
              # (ai,arr) = arr![i]
              = (ai,arr)