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