たけをです。

# 前置きでarrowsの話をしますが、あまり関係ないかも

 昨日、arrowsライブラリを少し触っていて、The Fun of Programming の記事
(http://www.soi.city.ac.uk/~ross/papers/fop.html)の4.1節にある同期回路の
例題をいじって遊んでいました。(なので、本体の記述をこちらをご参照頂きたく)

 で、ここにある回路が1回につき1クロック分の動作をするので、nクロック動か
した後の結果を見るための関数をこさえていました。例えば↓こんな感じです。

  runAuto2 = \ (A f) n -> let (c, f') = f False
                          in if n == 0 then c
                                 else runAuto2 f' (n-1)

しかし、nにかなり大きな数(数十万クロック〜100万クロック)をとると、どう
してもスタックがオーバーフローしてしまいます。

いろいろ試したのですがうまくいかず、唯一スタックが全然溢れなかったのが
↓こんな記述でした。

  runAuto2 = \ (A f) m -> let (c, f') = f False
                          in if c == m then c
                                 else runAuto2 f' m

 しかし引数がクロック数(実行ループ数)でなく、出力結果を見ているので
そもそも最初の関数とは違うものになっています。(例題に載っているのは
クロックカウンターなので、この場合はたまたま同じ動作を示すのですが)


 という事で、元の仕様で、nが十分大きくてもスタックが溢れないよう最適化
する方法は何かあるんでしょうか?
 あと、1つめの関数と2つめの関数では、見た目はほとんど変わらないのに、
動作結果に差が出るのは何故なんでしょう?


p.s. 余談なのですが、arrows って日本語ではどう書くべきなのでしょう?
monad はモナドですが。


--
IMAI Takeo <usitukai / osk.3web.ne.jp>

--
ML: haskell-jp / quickml.com
使い方: http://QuickML.com/