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

Programming with Arrows 読解 11

3.3 Recursive arrow bindings

ghci で SF (stream functions) を使えるようにするには :l SF2.hs、:set -Xarrows、:set +m の操作を前準備でしないといけない。結構めんどうだが、これらのコマンドをファイルに書き込んでおけば :script コマンドで ghci の設定をすることができる。

そこでつぎのコマンドをファイル sf.ghci に記述してスクリプトファイルを作成した。

:load SF2.hs
:set -XArrows
:set +m

そうしておいて ghci を起動した後、:script sf.ghci でスクリプトファイルを読み込めば、簡単に ghci の設定ができる。

Prelude> :s sf.ghci
[1 of 1] Compiling Main ( SF2.hs, interpreted )
Ok, modules loaded: Main.

閑話休題、本文に戻ろう。

point-free style でプログラムを記述するときも、再帰的定義は必須だった。arrow 記法でも再帰的定義をするためのキーワードが用意されている。point-free style で再帰的定義をするときは loop 関数を用いた。arrow 記法の場合は loop 関数の役割を rec キーワードが果たす。

point-free style で記述したフリップフロップ回路のプログラムを再掲する。

flipflop =
  loop (arr (\((reset,set),~(c,d)) -> ((set,d),(reset,c))) >>>
    nor *** nor >>>
    delay (False,True) >>>
    arr id &&& arr id)

point-free style の loop 関数に相当するものは、arrow 記法では rec キーワードだ。rec キーワード以下のブロックは動作が再帰する。上のフリップフロップは arrow 記法では次のようになる。

flipflop :: ArrowCircuit arr => arr (Bool,Bool) (Bool,Bool)
  flipflop = proc (reset,set) -> do
      rec c <- delay False -< nor reset d
          d <- delay True -< nor set c
      returnA -< (c,d)
    where nor a b = not (a || b)

上のプログラムでArrowCircuit クラスの多相関数は delay だけだ。SF2.hs ファイルには自前の delay 関数があるので、SF を ArrowCircuit のインスタンスにしなくても flipflop の定義は可能だ。そこで、ghci で試してみた。

*Main> let
*Main| flipflop = proc (reset,set) -> do
*Main|     rec
*Main|       c <- delay False -< nor reset d
*Main|       d <- delay True -< nor set c
*Main|     returnA -< (c,d)
*Main|   where nor a b = not (a || b)
*Main|
*Main> runSF flipflop [(False,False),(False,True),(False,True),(False,True),(False,False),(False,False),(True,False),(True,False),(True,False),(False,False),(False,False)]
[(False,True),(False,True),(False,False),(True,False),(True,False),(True,False),(True,False),(False,False),(False,True),(False,True),(False,True)]

ちゃんとフリップフロップの動作をしている。再帰的定義の場合でも、arrow 記法のほうが point-free style より分かりやすい。

<< 目次 >>
by tnomura9 | 2013-04-24 23:53 | Haskell | Comments(0)
<< Programming wit... 千愛 (Chia) >>