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>
> Gen slightly breaks the monad laws:<br>
><br>
>> arbitrary >>= return<br>
> is not the same as<br>
>> return () >>= const arbitrary<br>
> because each bind splits the generator, so you end up with a different<br>
> 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">
> If the observable value is "some random object" this is a safe fudge,<br>
> but if you want repeatable, it doesn't quite work. You need your<br>
> instances to be exactly identical, down to the associativity of binds,<br>
> 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 -> Int -> (a, StdGen) }<br>
<br>
instance Monad Gen where<br>
return a = MkGen $ \r _ -> (a,r)<br>
MkGen m >>= k = MkGen $ \r n -> let (a,r') = m r n in unGen (k a) r' n<br>
<br>
I'm pretty sure all the Gen primitives can be similarly redefined.<font color="#888888"><br></font></blockquote></div><br>And I'm guessing I haven't been or won't be the only one running into this issue.<br>
<br>Sean<br>