Is there a way to take a given monad&#39;s bind and wrap it to make it more lazy?  It doesn&#39;t seem like there should be, but I&#39;m being hopeful.<br><br><div class="gmail_quote">On Mon, Sep 13, 2010 at 3:21 PM, Daniel Fischer <span dir="ltr">&lt;<a href="mailto:daniel.is.fischer@web.de">daniel.is.fischer@web.de</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;"><div class="im">On Monday 13 September 2010 20:42:49, Alex Rozenshteyn wrote:<br>
&gt; I&#39;m trying to build a list where each entry depends on the previous one.<br>
&gt; Unfoldr seemed like a good idea at the time.<br>
&gt; Unfortunately, my values are monadic values (specifically RVars, from<br>
&gt; the random-fu package).  Okay, shouldn&#39;t be a problem; I just monadic<br>
&gt; bind and...<br>
&gt;<br>
&gt; &gt; -- example code<br>
&gt; &gt; updateCell :: Bool -&gt; RVar Bool<br>
&gt; &gt; updateCell False = return False<br>
&gt; &gt; updateCell True  = bernoulli (0.9 :: Double)<br>
&gt; &gt;<br>
&gt; &gt; sim = sequence $ take 20 $ unfoldr (\x -&gt; Just (x, x &gt;&gt;= updateCell))<br>
&gt;<br>
&gt; (return True)<br>
<br>
</div>So you get<br>
<br>
sequence [return True<br>
    , return True &gt;&gt;= updateCell<br>
    , (return True &gt;&gt;= updateCell) &gt;&gt;= updateCell<br>
    , ((return True &gt;&gt;= updateCell) &gt;&gt;= updateCell) &gt;&gt;= updateCell<br>
    , ... ]<br>
<div class="im"><br>
&gt;<br>
&gt; &gt; runRVar sim DevURandom<br>
&gt;<br>
&gt; [True,True,True,True,True,False,True,False,True,False,False,False,False,<br>
&gt;False,False,True,True,False,False,False]<br>
&gt;<br>
&gt; That output shouldn&#39;t be possible if I&#39;m doing things right...  It<br>
&gt; appears that each cell has an independent history.  I&#39;m stumped.<br>
&gt; Advice on threading monad input in general and random-fu in specific<br>
&gt; would be appreciated.<br>
<br>
</div>What you want would be something like<br>
<br>
iterateM :: (Monad m) =&gt; (a -&gt; m a) -&gt; a -&gt; m [a]<br>
iterateM act start = do<br>
    next &lt;- act start<br>
    rest &lt;- iterateM act next<br>
    return (start : rest)<br>
<br>
but that would only work if the bind is sufficiently lazy, otherwise you&#39;d<br>
have to iterate a given number of times.<br>
<br>
</blockquote></div><br><br clear="all"><br>-- <br><div dir="ltr"><div>          Alex R</div></div><br>