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 I'm stumped.