<div dir="auto"><div><div class="gmail_quote"><div dir="ltr">On Tue, Jun 19, 2018, 9:54 PM Dr.Koster <<a href="mailto:drkoster@qq.com">drkoster@qq.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="min-height:22px;margin-bottom:8px">In general infinite monadic recursion will leak, since the tail position is always >> or >>= instead of your own recursive function</div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">That seems a bit strong. Monadic recursion *can* leak, but it need not. >>= is typically lazy in its second argument, so it can produce structure lazily. Consider the free monad, for example:</div><div dir="auto"><br></div><div dir="auto">data Free f a = Pure a | Wrap (f (Free f a))</div><div dir="auto"><br></div><div dir="auto">instance Functor f => Monad (Free f) where</div><div dir="auto"> Pure a >>= f = f a</div><div dir="auto"> Wrap ff >>= f = Wrap $ fmap (>>= f) ff</div><div dir="auto"><br></div><div dir="auto">See how we can produce Wrap without using f? As long as the base functor isn't too large, this shouldn't leak.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="min-height:22px;margin-bottom:8px">, but under certain situations, e.g. IO without arguments, the compiler will figure there's no need to push new stack frame. But anyway it's better to checkout yourself rather relying on some weak assumptions.</div><div style="min-height:22px;margin-bottom:8px"><br></div><span class="m_3687407683116088054mail-footer">发自我的iPhone</span><div id="m_3687407683116088054original-content"><br><br><div><div style="font-size:70%;padding:2px 0">------------------ Original ------------------</div><div style="font-size:70%;background:#f0f0f0;color:#212121;padding:8px;border-radius:4px"><div><b>From:</b> Никита Фуфаев <<a href="mailto:kitttoran@gmail.com" target="_blank" rel="noreferrer">kitttoran@gmail.com</a>></div><div><b>Date:</b> Wed,Jun 20,2018 2:37 AM</div><div><b>To:</b> haskell-cafe <<a href="mailto:haskell-cafe@haskell.org" target="_blank" rel="noreferrer">haskell-cafe@haskell.org</a>></div><div><b>Subject:</b> Re: [Haskell-cafe] Memory leak in infinite recursion</div></div></div><br><div dir="ltr">Hello everyone<br><div><br></div><div>In C you can't implement main loop with recursion like</div><div>void mainLoop() {</div><div> doSomething();</div><div> mainLoop();</div><div>} </div><div>because without optimisations stack will overflow.</div><div>In haskell it's common to write</div><div>mainLoop = doSomething >> mainLoop, and it doesn't leak memory because of haskell's evaluation model.</div><div>Does memory leak or argument stack overflow happen in this case?</div><div>mainLoop = doSomething >> mainLoop >> exit ExitSuccess</div><div>What about this case?</div><div>mainLoopModeA = do</div><div> doSomething</div><div> when condition mainLoopModeB</div><div> mainLoopModeA</div><div>mainLoopModeB = do</div><div> doSomethingElse</div><div> when anotherCondition mainLoopModeA</div><div> mainLoopModeB</div><div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"><br>or this case?</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial">mainLoopModeA = do</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"> doSomething</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"> if condition</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"> then mainLoopModeB</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"> else mainLoopModeA</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial">mainLoopModeB = do</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"> doSomethingElse</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"> if anotherCondition </div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"> then mainLoopModeA</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"> else mainLoopModeB</div></div><br>-- <br><div class="m_3687407683116088054gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div dir="ltr"><div dir="ltr">Nikita Fufaev<br></div></div></div></div>
</div>
</div>_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div></div></div>