Concurrent Clean : Threading

スレッドの話ではない。関数プログラミングなどで、状態を次々と受け渡して行くような書き方を指していう言葉だ。
Haskellモナドを使ってThreadingを隠蔽してしまったのに対して、Cleanでは一意性型属性を使ってThreadingを陽に表現する。
ところで、Cleanでプログラミングをしていると、状態変数がわいわいと数が増えてしまって、それらの管理に困ってしまうことが起こりえる。たとえば・・・

f w # (_,f0,w) = fopen "file01.txt" FReadText w
      (_,f1,w) = fopen "file02.txt" FReadText w
      (_,f2,w) = fopen "file03.txt" FReadText w
      (_,f3,w) = fopen "file04.txt" FReadText w
      (_,f4,w) = fopen "file05.txt" FReadText w
      (_,f5,w) = fopen "file06.txt" FReadText w
      (a,f0,f1,f2,f3,f4,f5) = app f0 f1 f2 f3 f4 f5
      (_,w) = fclose f0 w
      (_,w) = fclose f1 w
      (_,w) = fclose f2 w
      (_,w) = fclose f3 w
      (_,w) = fclose f4 w
      (_,w) = fclose f5 w
    = (a,w)

こういうときに、状態変数を別の上位の状態変数に置き換えてやるようなことができたら便利だなぁとか思いました。つまり・・・

appWorld :: *a (*a -> (b,*a)) *World -> (b, *World)

readFile0 = appWorld f0 freadc
readFile1 = appWorld f1 freadc
readFile2 = appWorld f2 freadc
readFile3 = appWorld f3 freadc
readFile4 = appWorld f4 freadc
readFile5 = appWorld f5 freadc

みたいにグローバルに定義しておけば、

    # (c,w) = readFile0 w

のように、*Fileの代わりに*Worldを渡して関数を呼び出せるようになれば、トップレベルからは個々の状態変数だけでなく*Worldだけを渡せばよいようになる。
問題は、ぱっと思いつくところで、代入がないのでグローバルな定義を初期化できないことと、状態変数の破棄後にこれらの関数をどのように安全に取り扱うかということ。
まだ、かなり推敲の足りないアイデアなので、もうしばらく考えます。