<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>And just because this has not been explicitly stated: &nbsp;it's not just for aesthetic reasons that you couldn't do this with a pure function, but because it violates the semantics and gets you the wrong result. &nbsp;So for example, if you modified Tim's code to be</div><div><br></div><div><br></div><div><div><div>import Data.IORef</div><div>import System.IO.Unsafe</div><div><br></div><div>mkNext :: (Num a) =&gt; IO a</div><div>mkNext = do</div><div>&nbsp;&nbsp;ref &lt;- newIORef 0</div><div>&nbsp;&nbsp;return . unsafePerformIO $</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; do</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; modifyIORef ref (+1)</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; readIORef ref</div><div><br></div><div>main :: IO ()</div><div>main = do</div><div>&nbsp;&nbsp;foo &lt;- mkNext</div><div>&nbsp;&nbsp;print foo</div><div>&nbsp;&nbsp;print foo</div><div>&nbsp;&nbsp;print foo</div><div><br></div></div><div><br></div><div>Then the output that you will see (with GHC at least) is</div><div><br></div><div>1</div><div>1</div><div>1</div><div><br></div><div>because the compiler assumes that it only needs to evaluate foo once, after which it can cache the result due to assumed referential transparency.</div><div><br></div><div>- Greg</div><div><br></div><div><br></div><div><br></div></div><div><div>On Oct 21, 2009, at 11:40 AM, Tim Wawrzynczak wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">True...here we go then:<br><br>import Data.IORef<br>import System.IO.Unsafe<br><br>mkNext :: (Num a) =&gt; IO (IO a)<br>mkNext = do<br>&nbsp; ref &lt;- newIORef 0<br>&nbsp; return (do modifyIORef ref (+1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readIORef ref)<br> <br>next :: IO ()<br>next = do<br>&nbsp; foo &lt;- mkNext<br>&nbsp; a &lt;- sequence [foo,foo,foo]<br>&nbsp; putStrLn $ show a<br><br><br>running next will print [1,2,3] which is the result of calling 'foo' 3 times.<br><br>But technically then, mkNext is just an IO action which returns an IO action ;)<br> and not a function which will return the next value each time it is called,<br>hence the need to extract the value from mkNext, then use it...<br><br>Cheers,<br>Tim<br><br><br><div class="gmail_quote">On Wed, Oct 21, 2009 at 1:30 PM, minh thu <span dir="ltr">&lt;<a href="mailto:noteed@gmail.com">noteed@gmail.com</a>&gt;</span> wrote:<br> <blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">2009/10/21 Tim Wawrzynczak &lt;<a href="mailto:inforichland@gmail.com">inforichland@gmail.com</a>&gt;<br> <div class="im">&gt;<br> &gt; Here's an example in the IO monad:<br> &gt;<br> &gt; import Data.IORef<br> &gt; import System.IO.Unsafe<br> &gt;<br> &gt; counter = unsafePerformIO $ newIORef 0<br> &gt;<br> &gt; next = do<br> &gt; &nbsp; modifyIORef counter (+1)<br> &gt; &nbsp; readIORef counter<br> &gt;<br> &gt; Naturally, this uses unsafePerformIO, which as you know, is not kosher...<br> <br> </div>But you don't close around the Ref like in your schemy example.<br> <br> mkNext = do<br> &nbsp;ref &lt;- newIORef 0<br> &nbsp;return (do modifyIORef ref succ<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; readIORef ref)<br> <br> mimic your other code better.<br> <br> Cheers,<br> <font color="#888888">Thu<br> </font></blockquote></div><br> _______________________________________________<br>Haskell-Cafe mailing list<br><a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br></blockquote></div><br></body></html>