人気ブログランキング | 話題のタグを見る

Programming with Arrows 読解 3

1.3 Arrows as computations

Haskell で使われるモナドの使い方は2つある。ひとつは、IO モナドや ST モナドのように、手続き型のプログラムと参照透明な関数プログラムのインターフェースとしての使い方だ。もうひとつは、パーサー・コンビネータの例のように、純粋関数的なプログラムにDSL (Domain Specific Lnguage) のような構造的なインターフェースを提供する事だ。

パーサー・コンビネータなどの、様々なコンビネータはモナドとして記述する事によって、共通のインターフェースで記述する事ができる。これらの利点は数多くある。第1に、モナドというインターフェースが使いやすく、強力なツールである事。第2に、ライブラリのデザイナーはモナドによって一貫したインターフェースが設計できる事。第3に、多くのライブラリで、使用法を統一する事ができる事。作成する方も作りやすいし、ユーザもライブラリの使用法について迷わない、などだ。

Haskell のプログラムの中に、このような構造的なインターフェースをモナドによって導入するのは便利だが、モナドにはいろいろな制限がある。例えばバインド演算子を通じて伝達するのが、特定の型の値でなければならないという事などだ。Arrow ライブラリはモナドの利点を生かしながら、モナドの制限を緩めて構造的なインターフェースとしての役割を拡充している。

1.4 Arrow laws

モナドのプログラミングであまり触れられない要件にモナド則 ( monadic laws ) がある。普段のモナドのプログラミングでモナド則を意識する事はほとんどない。しかし、モナド則は do ブロックが作動するために必須の法則なのだ。

数式の結合則を例に挙げると、a + b + c という計算がどのような順序で行われるかということにあまり注意を払わないで済むのは、(a + b) + c = a + (b + c) という法則が常に成立しているためだ。

Arrow でも同じようなことが言える。前節で示した >>> 演算子のプログラムに括弧が用いられていなかったのは、>>> 演算子にも + の場合と同じような結合法則が成り立っているからだ。

同じ事は arr 関数にも言える。arr 関数と >>> 演算子の分配法則によって、次のプログラムは、

count w = Kleisli readFile >>>
      arr words >>> arr (filter (==w)) >>> arr length >>>
      Kleisli print

次のプログラムと同値であることが保証されている。

count w = Kleisli readFile >>>
      arr (words >>> (filter (==w)) >>> length) >>>
      Kleisli print

このように、個々の Arrow の定義に注意を払わずに記述してもその同値性が保証されているという事はプログラムの作成に計り知れない利点をもたらす。モナド則は表に現れないが、このように重要な働きをしているのだ。

しかし、実際のプログラミングではモナド則を破るようなモナドの記述も必要になってくる。Arrow でも同じような状況が発生する場合があり、厳密にモナド則に従う事が、プログラミングの自由度を束縛する事がある。このため、これ以上厳密なモナド則にはこのチュートリアルでは立ち入らない。

<< 目次 >>
by tnomura9 | 2013-04-13 05:41 | Haskell | Comments(0)
<< Programming wit... Programming wit... >>