[Haskell-cafe] How to increment an Int in Haskell (stack overflow issue)

Lennart Augustsson lennart at augustsson.net
Wed Mar 25 15:33:05 EDT 2009


Make an AState with two !Int fields and increment those.

On Wed, Mar 25, 2009 at 8:00 PM, Tim Bauer <bauertim at eecs.orst.edu> wrote:
> I have a program that is currently blowing out the stack,
>   Stack space overflow: current size 8388608 bytes.
>   Use `+RTS -Ksize' to increase it.
> I am pretty sure I get to the end of the computation that
> increments various statistic counters (lazily?) and only
> when I go to print them out at the end, do things fail.
>
> I have state monad transformer (StateT) that is keeping the counters
> among other things. The counters are stored in a pair within a larger
> data structure.
>
>> data AState s a = AS { ...
>>                       asStats :: (Int,Int)
>>                       ...
>>                     }
>
> to increment them I initially just simply applied either of
>> incFst, incSnd :: (Int,Int) -> (Int,Int)
>> incFst (x,y) = (x + 1,y)
>> incSnd (x,y) = (x, y + 1)
>
> to the current pair. I thought this was safe since primitive
> arithmetic was strict, but when I go to print the counter
> out (evaluate it), it blows apart.
>
> I first decided this was because the addition was somehow not
> strict and I was getting:
>  (0 + 1 + 1 ...millions of times..., ....)
> and the evaluation of that first coordinate blew things apart.
> So I tried was adding a strictness annotation to the arguments.
>> incFst (!x,y) = (x + 1,y)
>> incSnd (x,!y) = (x, y + 1)
>
> No dice (I also tried using seq manually all over the place
> to no avail). Just for fun, I tried both of
>
>> incFst _ = (0,0)
>> incSnd _ = (0,0)
>
> and
>
>> incFst (x,y) = (x,y)
>> incSnd (x,y) = (x,y)
>
> The problem goes away. But maybe an optimization is covering
> up the crime. So I tried
>
>> incFst (x,y) = (y,x)
>> incSnd (x,y) = (y,x)
>
> And indeed this again crashes. Any hints as to what is going on?
>
> If it is relevant, here is my code to access the counter within
> the state monad
>
>> countFst :: StateT (AState s a) IO ()
>> countFst = modify $ \as -> as{asStats = incFst (asStats as)}
>
> and the monad transformer I am using is
>
>> import Control.Monad.State.Strict
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list