[Haskell-cafe] Plug space leak with seq. How?
Daniel Fischer
daniel.is.fischer at googlemail.com
Thu Jun 9 19:38:01 CEST 2011
On Thursday 09 June 2011, 18:41:40, Alexey Khudyakov wrote:
> On 09.06.2011 20:09, Yves Parès wrote:
> > Is it not:
> > > noLeak :: State Int ()
> > > noLeak = do
> > >
> > > a <- get
> >
> > *>* *let a' = (a + 1)
> >
> > > a' `seq` put a'*
> > > noLeak
> >
> > ??
>
> Indeed. Now I understand. It didn't work for me earlier because of
> different behavior of 'forever' in ghci and compiled code.
>
> This function leaks in ghci and do not in compiled code without
> optimizations (with optimizations GHC is smart enough to make
> everything strict).
>
> > noLeak = forever $ do { a <- get; let a' = a+1; a' `seq` put a' }
>
> Function with explicit recursion do not leak in both cases.
>
> > noLeak = do { a <- get; let a' = a+1; a' `seq` put a'; noLeak }
>
> What causes this difference?
forever a = a >> forever a
doesn't tie to itself without optimisations, so my guess is that it gets
expanded when you run/eval/execState it in ghci, building the thunk
a >> a >> a >> a >> ...
If you define
forever' a = let a' = a >> a' in a'
the variant using forever' runs in constant space in ghci.
This, like the explicit recursion, builds a cyclic structure, hence avoids
the leak.
More information about the Haskell-Cafe
mailing list