
On Sat, Nov 14, 2015 at 11:10:15AM +0100, martin wrote:
newtype Logger evt dom log = Lgr {runLogger :: Timed evt -> dom -> (log, Logger evt dom log)}
runSim :: (Ord evt, Monoid log) => SimBehaviour evt dom log -> SimState evt dom log -> SimState evt dom log runSim (!lgr, !hdr, xtp) (!log,!dom,!evq) = case step of Nothing -> (log, dom, evq) -- end of simulation Just (newEvq, newDom, newHdr, newLgr, newLog) -> runSim (newLgr,newHdr,xtp) (newLog,newDom,newEvq) where -- check for end conditions or run handler step = do (evt, evts) <- H.view evq -- no more Events -> Nothing if xtp (evt,dom) then Nothing else let (evq', dom', hdr') = runHandler hdr evt dom (log',lgr') = runLogger lgr evt dom' -- <-- -- append new event and new log entries in return (evq'<>evts, dom', hdr', lgr', log'<>log) -- <--
addLgr (lgr1) (lgr2) = Lgr lgr where lgr tev dom = let (log1', lgr1') = runLogger lgr1 tev dom (log2', lgr2') = runLogger lgr2 tev dom (!log') = log2' <> log1' -- x -- -- in (log2', addLgr lgr1' lgr2') in (log', addLgr lgr1' lgr2')
[...]
Could it be that this is because ! does not fully evaluate its argument, but just to WHNF? Or is there a more obvious reason, I just fail to see.
Yes, forcing a list is more-or-less useless, most of the time. All you're doing is checking whether the length is zero or non-zero.
Where to go from here?
The first thing to do would be to check whether import Control.DeepSeq ... !log' = deepseq (log2' <> log1') solves the space leak. If it does then you have found the problem. That's not the same thing as finding a solution though! There are plenty of pre-rolled logging solutions available. I think I'd just suggest choosing one of those, rather than implementing your own. Tom