This is a small example of problem I described (don't ask me what it
does):

    foo :: (() -> () -> [()] -> [()]) -> () -> [()] -> [()]
    foo k =
      \_ xs -> concatMap ($ [head xs]) [bar]
     where
      bar =
        let k' = k undefined undefined
        in  \xs ->
              let k'' = [k' xs]
              in  (() : (foldr1 (>>) k''))

    k = foo (\_ -> k)
    --k a = foo (\_ -> k) a
    r = k undefined [] !! 4000
    main = print r

It is very sensitive to small changes, so be sure to use a high-quality
cut-n-paste implementation.  Basically, this code has a memory leak
through xs; the xs passed to k' comes from the xs passed to foo, and is
never forced, so a chain of thunks is built.  If you run the code as is,
either with time or heap profiling, you will see everything charged to
k.  If you instead use the commented version of k, you will see
everything charged to foo, as expected.  The command I run to test this
is

    ghc --make -prof -auto-all Logic.hs && ./a.out +RTS -hc && hp2ps -c a.out.hp

I'm using ghc 6.4.1 from Debian unstable.

I'll copy this into a bug report too.  I can try to explain what I did
to arrive at this code if it wolud help, but it's a long story....

Andrew
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to