haskell - IO/Monadic assign operator causing ghci to explode for infinite list -
Consider the following program. It goes on forever and nothing is useful, but memory consumption in ghci is constant:
- NoExplode.hs module main (main) where exam :: [int] -> gt; ; Io (test) lst = Print "Test" RLISISLS RIlist :: [int] - & gt; IO () rList [] = Return () rList (x: xs) = do rList xs main = test [1 ..]
Now consider the lower revised version of the above. When this program is run in ghci memory explosion. The only difference is that the print "test"
is specified in the x
block test
.
- Explode.hs module main (main) where test :: [int] - & gt; IO () test lst = do x & lt; - Print "test" rList lst rList :: [int] - & gt; IO () rList [] = Return () rList (x: xs) = do rList xs main = test [1 ..]
Why the print "test changes" / Code> to
x & lt; - Print "test"
Due to blowing ghci?
ps When I am trying to understand, I have come to this, even then, the problem here (I think) basically thank the above distilments
Disclaimer : I'm not a GHCI expert, and not too good with the GHC core Now when I've lost my credibility, So try to understand what happens:
GHCI and CAF
GHCI:
Generally, any value But top-level expression of loaded modules (otherwise CAF or Constant applicant is known as form) is placed between the assessment.
Your programs dump
non-blast version: h3>
❯ ghc SO.hs -ddump- Simpl -fforce-recomp -O0 -dsuppress-all [1 of 1] Compilation Main (SO.hs, SO .o) =================== Organized core = =================== results reinforce core size = {Terms: 29, type: 28, coercions: 0} $ dShow_rq2 $ dShow_rq2 = $ fShow [] $ fShowChar Rec {RList_reI rList_reI = \ ds_dpU - & gt; Ds_dpu _ {[] - & gt; $ FMonadIO Return (); : X_aho xs_ahp - & gt; RList_reI xs_ahp} end RE} main key => & Gt; $ FMonadIO (print $ dShow_rq2 (unpackCString # "test")) (rList_reI (enumFrom $ fEnumInt (i # 1))) chief = runMainIO main
The location of the important part
[1 ..]
, almost at the end:enumFrom $ fEnumInt (I # 1))
See you as The list is not CAF, but what happens if we use the explosion version instead?
Exploding version
❯ ghc SO.hs -ddump-simpl - Fforce-recomp -O0 -dsuppress-all [1 1] Compiling men (SO.hs, SO.o) ==================== Clean core === Clean core = of ====== =========== results size {Terms: 32, type: 31, coercions: 0} $ dShow_rq3 $ dShow_rq3 = $ fShow [] $ fShowChar Rec {rList_reI RList_reI = \ ds_dpV - & gt; _ _ [[] - & gt; $ FMonadIO Return (); : X_ahp xs_ahq - & gt; RList_reI xs_ahq} End Rec} lst_rq4 lst_rq4 = enumFrom $ fEnumInt (I # 1) Main main = & gt; & Gt; = $ FMonadIO (print $ dShow_rq3 (unpackCString # "test")) (\ _ - & gt; rList_reI lst_rq4) Main main = RunMainIO main
Suddenly there is a new top-level expression, I.e.
lst_rq4
, which generates the list and as seen before, GHCI retains the evaluation of high-level expressions, so thelst_rq4
will also be retained .Now there is an option to abandon evaluation:
After switching on+ r
, all evaluations of top-level expressions are omitted after each evaluation (they Are still created during an evaluation).
But since "they are still created during an evaluation" even : set + r
will not help you in this matter. Unfortunately, I can not answer why GHC introduces a new top-level expression.
Why can it be in customized code?
The list is still a top-level expression:
main2 main2 = eftInt 1 2147483647
Strange, GHC actually Does not make an infinite list, because int
is bound. / P>
How to get rid of the leak?
If you put the list in the these exams then in this case you can get rid of it:
test = do x & lt; - print "test" rList [1 ..]
This will prevent GHC from making top-level expressions.
However, I can not really give a general advice on this. Unfortunately, my Haskell-Fu is not enough yet.
Comments
Post a Comment