Interesting. We generally have pure x = IO (\ s -> (# s, x #)) IO m *> n = IO (\ s -> case m s of (# new_s, a #) -> unIO ((const n) a) new_s) so main = let loop () = IO (\s -> (# s, () #)) *> loop () in loop () ==== let loop () = IO (\s -> case (\s' -> (# s', () #)) s of (# new_s, a #) -> unIO ((const (loop ()) a) new_s) in loop () ==== let loop () = IO (\s -> case (# s, () #) of (# new_s, a #) -> unIO (loop ()) new_s) in loop () ==== let loop () = IO (\s -> unIO (loop ()) s) in loop () My only guess is that *somehow* this is getting memoized and expanding under the lambda to let loop () = IO (\s -> unIO (IO (\s -> unIO ......)) s) in loop () but I know nothing about GHCi internals, so that seems as weird to me as it does to you. On Fri, Nov 4, 2016 at 10:58 AM, Tom Ellis <tom-lists-haskell-cafe-2013@jaguarpaw.co.uk> wrote:
On Fri, Nov 04, 2016 at 02:44:00PM +0000, Tom Ellis wrote:
Can anyone explain why this leaks space:
main :: IO () main = let loop () = return () *> loop () in loop ()
whilst this doesn't:
main :: IO () main = let loop = return () *> loop in loop
More strangely, the space leak only appears in ghci (and runhaskell). When compiled there is no such space leak.
Tom _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.