[Haskell-cafe] stack overflow when using ST monad
Gregory Wright
gwright at comcast.net
Thu Aug 24 08:43:57 EDT 2006
Hi Udo,
On Aug 24, 2006, at 7:22 AM, Udo Stenzel wrote:
> Hi Gregory,
>
> Gregory Wright wrote:
>> step :: Tag s -> ST s (Maybe Integer)
>> step t = do
>> c <- readSTRef (count t)
>> s <- readSTRef (state t)
>> writeSTRef (count t) (c - 1)
>> writeSTRef (state t) (nextState s)
>> if (c <= 0) then return Nothing else return (Just c)
>
> just looking at the program, this seems to be the problem: writeSTRef
> does not force the evaluation of the stored value. So after repeated
> calculation, you end up storing not the current counter and state, but
> something like (nextState (...(nextState (nextState initState))...)).
> The counter is evaluated for the conditional at the end, so it doesn't
> exhibit this problem. Your computation runs to its end, then that
> deeply nested expression is evaluated and exhausts the control stack.
> Try this instead:
>
>> writeSTRef (state t) $! nextState s
>
> If TagState is a more complicated data type, you may also need strict
> fields in there.
>
> [This comes up so often, shouldn't there be an FAQ about it
> somewhere? It
> could even offer a guideline along the lines of "Whenever you
> repeatedly
> update some value, chances are that you want to force strict
> evaluation."]
>
I agree this should be a FAQ. Perhaps I should write it up for the
performance section of the wiki? Looking back I see my mental error
was that I thought I was doing what you and everyone else correctly
suggested:
writeSTRef (state t) $! nextState s
but what I actually typed was
writeSTRef (state t) (nextState $! s)
which of course doesn't help. Another telling example
of the fact that coffee is not an entirely adequate substitute for
sleep.
Best,
Greg
>
> Udo.
> _______________________________________________
> 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