Concurrent Clean : 参照型

というわけで、参照型を作ってみた。Cleanでは配列を破壊的に更新できるという特徴を生かして、マジックプログラミングしました。

::*Ref a

reference :: !.a -> *(Ref .a)
copy :: !*(Ref .a) -> (!*(Ref .a), !*(Ref .a))
apply :: !(.a -> .a) !*(Ref .a) -> *(Ref .a)
access :: !(.a -> (.b,.a)) !*(Ref .a) -> (!.b, !*(Ref .a))

とりあえず、上のような関数セットを用意して、

Start w
    # ri = reference 1
      (ri1,ri2) = copy ri
      ls1 = process 1 ri1
      ls2 = process 2 ri2
      ls = interleave ls1 ls2
    = take 10 ls

process a ri
    # (e,ri) = access f ri
    = [e:process a ri]
  where
    f i = (i,i+a)

interleave [a:aa] bb
    = [a:interleave bb aa]

のようなプログラムが、

[1,2,4,5,7,8,10,11,13,14]

のような出力になります。
特徴は、

  • 参照型の値は、字句上の順に更新されるのではなく、実行時の順に交信される
  • 参照型は共有はできないが、コピーはできる
  • 参照型へのアクセスは、一意型によって意味的に安全にアクセスできる