Concurrent Clean : 便利関数

[id:lethevert:20060326]の問題を解くにあたって、2つほど便利関数ができました。

(\|) infixl 1
(\|) f p :== if p f id

interleave :: ![a] ![a] -> [a]
interleave as bs = il1 as bs
  where
    il1 []     _  = []
    il1 [a:ar] bs = [a:il2 ar bs]

    il2 _  []     = []
    il2 as [b:br] = [b:il1 as br]

まず、interleaveは、リストを2つ取って、リストの要素を交互に並べた新しいリストを作ります。
たとえば、次のように使います。

Start w
    # (f,w) = stdio w
    # f = f --> ([0..5] --> map fwritei
                        --> flip interleave $ repeat $ fwrites "\n"
                        --> reelU)
    # (ok, w) = fclose f w
    = w

interleaveで、1つ1つの出力の間に、改行を挟み込みます。出力はこうなります。

0
1
2
3
4
5

もう一つの、「\|」は、「-->」を使ったスタイルのプログラミングの一部にガードを入れられるようにします。
「$」の優先順位を2にして、「-->」との中間の優先順位にすることで、次のように書けるようにしました。

Start w
    # (f,w) = stdio w
    # f = f --> ([0..10] --> map fwritei
                         --> flip interleave $ repeat $ fwrites "\n"
                               \| False
                         --> reelU)
    # (ok, w) = fclose f w
    = w

こうすることで、改行を挟み込む処理を条件付きにできます。この場合は、条件式がFalseなので、改行が挟み込まれません。出力はこうなります。

012345

Concurrent Clean : 副作用と一意型(4)

久しぶりに[id:lethevert:20060222:p2]の続きです。
一意型を使うアイデアとして、モナドスタイルと高階関数の2通りのスタイルを試してみましたが、だいぶ考えが整理されてきたというか、手駒が増えてきたというか。
だんだん、2種類のアプローチを融合したスタイルができあがってきました。上の便利関数は、その方向性に沿ったものです。
で、下は、実験的な試み。ファイルオープンやクローズも含めて、この新しいスタイルに編みこめるかを考えてみました。無名関数を使うことで、柔軟に多段階の組み合わせが可能です。

Start w
    = w --> stdio
        --> \(f,w) = w --> fclose (f --> ([0..10] --> map fwritei
                                                  --> reelU))
                       --> snd