[Haskell-cafe] How to implement nested loops with tail recursion?

sdiyazg at sjtu.edu.cn sdiyazg at sjtu.edu.cn
Wed Sep 19 20:00:44 CEST 2012


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 at gmail.com>
收件人: sdiyazg at sjtu.edu.cn
抄送: haskell-cafe at 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 at 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



More information about the Haskell-Cafe mailing list