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@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to