So how do I force IO actions whose results are discarded (including IO ()) to be strict? main = do s<-newIORef (1::Int) let f :: Int -> Int -> IO Int f 0 !acc = return acc -- note strict accumulator f n !acc = do v <- modifyIORef s (+2) >>readIORef s -- reading immediately after writing f (n-1) (v+acc) f 1000000 100 >>= print readIORef s>>=print runs OK, while main = do s<-newIORef (1::Int) let f :: Int -> Int -> IO Int f 0 !acc = return acc -- note strict accumulator f n !acc = do v <- modifyIORef s (+2) >>return 1 f (n-1) (v+acc) f 1000000 100 >>= print readIORef s>>=print , main = do s<-newIORef (1::Int) let f :: Int -> Int -> IO Int f 0 !acc = return acc -- note strict accumulator f n !acc = do v <- modifyIORef s (+2) >>readIORef s>>return 1 f (n-1) (v+acc) f 1000000 100 >>= print readIORef s>>=print and main = do s<-newIORef (1::Int) let f :: Int -> Int -> IO Int f 0 !acc = return acc -- note strict accumulator f n !acc = do v <- (>>return 1) $! (modifyIORef s (+2) >>readIORef s) f (n-1) (v+acc) f 1000000 100 >>= print readIORef s>>=print all overflows after correctly printing the first number ----- 原始邮件 ----- 发件人: "Johan Tibell" <johan.tibell@gmail.com> 收件人: sdiyazg@sjtu.edu.cn 抄送: haskell-cafe@haskell.org 发送时间: 星期四, 2012年 9 月 20日 上午 1:28:47 主题: Re: [Haskell-cafe] How to implement nested loops with tail recursion? On Wed, Sep 19, 2012 at 7:24 PM, <sdiyazg@sjtu.edu.cn> wrote:
main = do let f 0 acc = return acc f n acc = do v <- return 1 f (n-1) (v+acc) f 1000000 100 >>= print
Try this main = do let f :: Int -> Int -> IO Int f 0 !acc = return acc -- note strict accumulator f n acc = do v <- return 1 f (n-1) (v+acc) f 1000000 100 >>= print