
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."] Udo.