たけをです。
# 前置きで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/