
A follow-up question.
I still haven't got the monadic version working, and the real use case involves IO actions.
I looked at http://www.haskell.org/haskellwiki/Recursion_in_a_monad and adapted the 'tail-recursive' snippet on the page into
main = do
let
f 0 acc = return acc
f n acc = do
v <- return 1
f (n-1) (v+acc)
f 1000000 100 >>= print
which still blows the memory.
And so does this program
main = do
s<-newIORef (0::Int)
mapM_ (\i->modifyIORef s (+1)) [0..10000000]
readIORef s>>=print
Why?
----- 原始邮件 -----
发件人: sdiyazg@sjtu.edu.cn
收件人: haskell-cafe@haskell.org
发送时间: 星期四, 2012年 9 月 20日 上午 12:08:19
主题: Re: How to implement nested loops with tail recursion?
Now I have discovered the right version...
main = print (f 1 0::Int) where
f i s = (if i<=20000 then (f (i+1) (s + g 1 0)) else s) where
g j s = (if j<=20000 then (g (j+1) (s + i*j)) else s)
----- 原始邮件 -----
发件人: sdiyazg@sjtu.edu.cn
收件人: haskell-cafe@haskell.org
发送时间: 星期三, 2012年 9 月 19日 下午 11:35:11
主题: How to implement nested loops with tail recursion?
I need to implement fast two-level loops, and I am learning using seq to make calls tail-recursive.
I write programs to compute
main = print $ sum [i*j|i::Int<-[1..20000],j::Int<-[1..20000]]
This program (compiled with -O2) runs twenty times slower than the unoptimized (otherwise the loop gets optimized out) C version.
But it seems to run in constant memory, so I assume that it has been turned into loops.
#include