Open deepakjois opened 12 years ago
I looked into this a bit. After doing a bit of profiling I'm pretty sure the problem is that logoseg
and modifyTrail
are too lazy:
-- Adds a segment to the accumulated path.
logoseg :: Monad m => (Segment R2) -> TurtleT m ()
logoseg seg = ST.modify
(\(TState d ang p) ->
TState d ang $ modifyTrail
(\(Trail xs c) -> Trail (rotate ang seg:xs) c) p)
modifyTrail :: (Trail v -> Trail v) -> Path v -> Path v
modifyTrail f (Path ((p, t) : ps)) = Path $ (p, f t) : ps
modifyTrail _ p = p
Each time logoseg
is called, instead of actually updating the state, it just creates a thunk -- only when the final path is needed at the end are all these thunks actually evaluated.
Not sure off the top of my head what the best way is to add the required strictness.
This blog post may have some useful pointers. http://blog.johantibell.com/2012/02/forcing-values-returned-from-monadic.html
Very relevant stack overflow post: http://stackoverflow.com/questions/7998458/why-does-this-simple-use-of-the-state-monad-cause-a-stack-overflow
@byorgey on IRC suggests
-rtsopts
(cabal install --ghc-options="-rtsopts"
)+RTS -hT -RTS
Also relevant: http://blog.ezyang.com/2011/05/anatomy-of-a-thunk-leak/
repeat 4000 [repeat 34 [fd 12 rt 10] rt 90]
causes stack overflow.