[Haskell-cafe] Daunting heap profile when using (<>)

Tom Ellis tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk
Sat Nov 14 12:43:47 UTC 2015


On Sat, Nov 14, 2015 at 01:28:58PM +0100, martin wrote:
> newtype Condition a  = Cnd {checkCnd :: a ->  (Bool, Condition a)}
> 
> -- | Create a 'Condition' from two conditions which holds when one of
> -- them holds.
> cor :: Condition a -> Condition a -> Condition a
> cor c1 c2 = Cnd cnd
>         where
>             cnd a = let (b1', c1') = checkCnd c1 a
>                         (b2', c2') = checkCnd c2 a
>                     in if b1' || b2'
>                        then (True,  cor c1' c2')
>                        else (False, cor c1 c2)
> 
> 
> logWhen :: Monoid log => Condition (Timed evt,dom) -> Logger evt dom log -> Logger evt dom log
> logWhen cnd lgrIn = Lgr lgr'
>         where
>             lgr' tev dom =
>                     case checkCnd cnd (tev, dom) of
>                         (True, cnd') -> let (log', lgrIn') = runLogger lgrIn tev dom
>                                          in (log', logWhen cnd' lgrIn')
>                         (False,cnd')   -> (mempty, logWhen cnd' lgrIn)
> 
> Am I holding on to some data where I shouldn't? I cannot see it.

Sure, this

    (log', lgrIn') = runLogger lgrIn tev dom

allocates a thunk for log' that holds on to tev and dom.  Even if they are
small, holding onto them for thousands or millions of iterations is going to
leak a lot of space.

The only way to avoid this is to force log' sufficiently far that tev and
dom can be released.

Tom


More information about the Haskell-Cafe mailing list