
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

Make an AState with two !Int fields and increment those.
On Wed, Mar 25, 2009 at 8:00 PM, Tim Bauer
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@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Am Mittwoch 25 März 2009 20:00:40 schrieb Tim Bauer:
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?)
Far too 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) ... }
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)}
This is where the strictness you added to incFst is hidden again. countFst writes the thunk (\as -> as{asStats = incFst (asStats as)}) to the state, incFst isn't even called yet. To force the evaluation, a) make the stats two strict (!Int) fields b) evaluate the state, like in countFst = do as <- get let a = asStats1 as as1 = as{asStats1 = a+1} put $! as1
and the monad transformer I am using is
import Control.Monad.State.Strict

bauertim:
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) ... }
I would always, always write this as: data AState s a = AS { ... , asStatsX, asStatsY :: !Int , ... } and compile with: ghc -O2 -funbox-strict-fields Simple heuristic: unless otherwise specified, atomic types should always be strict fields. -- Don
participants (4)
-
Daniel Fischer
-
Don Stewart
-
Lennart Augustsson
-
Tim Bauer