Concurrent Clean : エラー処理イベントの登録 -> Erlang風のマルチプロセスプログラミング
ファイル操作やDB操作などで、エラーが発生したときにいちいちログ出力するコードを記述するのではなく、エラー処理イベントを発生させて登録してあるイベント関数をコールバックしてもらうという構造にする方が嬉しい。せっかく関数がファーストクラスなのだから、そういうことはぜひともやりたいのだが、副作用なしの言語でそういうことが書けるだろうか?
次のような定義があって、
::*SQL` ::*SQL = {sql :: *SQL` ,err :: [*SQL -> *SQL]} addErrorEvent :: (*SQL -> *SQL) *SQL -> *SQL addErrorEvent f (sql=:{err}) = {sql & err = [f:err]}
エラー発生時に次のように呼んでやる。
case ... of ... Error (sql=:{err}) = sql --> seq err
これでイベントの登録とコールバックはできるのだけれど、このイベントが受け取ったエラーステータスをどうやって外の世界に伝えればよいのかということは難問だ。
traceのようにプログラムの外部に出力するのみで、プログラムの内部の動作に影響を与えないような特殊な関数をライブラリで提供してやって、それを利用するという方法もあるが、それはアドホックだし、拡張性が低い。
しかし、traceの発想は有意義で、そこから発想を拡張していけば、Erlangのようにいくつものプロセスを用意して、各プロセス内では副作用なく記述しているのだけれど、プロセス間の通信を通して副作用を表現するようなモデルに発展させることができるような気がする。この方法は、モナドや一意型変数とは違って、トップレベルという特殊な装置を使わなくても副作用を取り扱うことができるので、より柔軟にプログラムを記述できるのではないだろうか?