Concurrent Clean : ガード
下で紹介した「\|」演算子ですが、「?|」の方がいいような気がしてきた。
こんな感じ。どう?
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 (?|) infixl 1 (?|) f p :== if p f id
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