On Tue, Feb 2, 2010 at 20:25, David Menendez <span dir="ltr"></span>wrote:<br><div class="gmail_quote"><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 Tue, Feb 2, 2010 at 1:48 PM, Ryan Ingram wrote:<br>
&gt; Gen slightly breaks the monad laws:<br>
&gt;<br>
&gt;&gt; arbitrary &gt;&gt;= return<br>
&gt; is not the same as<br>
&gt;&gt; return () &gt;&gt;= const arbitrary<br>
&gt; because each bind splits the generator, so you end up with a different<br>
&gt; seed passed to arbitrary in these two cases.<br></div></blockquote><div><br>Ah yes, that was exactly the problem.<br> </div><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">
&gt; If the observable value is &quot;some random object&quot; this is a safe fudge,<br>
&gt; but if you want repeatable, it doesn&#39;t quite work.  You need your<br>
&gt; instances to be exactly identical, down to the associativity of binds,<br>
&gt; in order to get the same results.<br>
<br>
</div>We could avoid that problem by redefining Gen as a state transformer monad.<br>
<br>
newtype Gen a = MkGen { unGen :: StdGen -&gt; Int -&gt; (a, StdGen) }<br>
<br>
instance Monad Gen where<br>
    return a = MkGen $ \r _ -&gt; (a,r)<br>
    MkGen m &gt;&gt;= k = MkGen $ \r n -&gt; let (a,r&#39;) = m r n in unGen (k a) r&#39; n<br>
<br>
I&#39;m pretty sure all the Gen primitives can be similarly redefined.<font color="#888888"><br></font></blockquote></div><br>And I&#39;m guessing I haven&#39;t been or won&#39;t be the only one running into this issue.<br>

<br>Sean<br>