We're all guilty of throwing around the bang patterns to fix performance problems, and that is a reasonable solution. But if you wish to understand the problem, see if you can narrow down much of your leak to a specific field within one of your types, then you can look at epoch and sub functions and identify why that particular field is not being fully evaluated by the time you have returned from epoch. Hopefully it will be obvious in hindsight and you will not run into this next time you have similar code. GHCI's debugger may also give you a nice way to determine where your problem lies.