<div dir="ltr"><div><div><div>No, newIORef does not itself change any state. It returns an IO value because each invocation returns a different IORef, but there isn't any way to tell how many or which IORefs were created. So newIORef 0 >> newIORef 0 doesn't differ in any way from newIORef 0, except in that an additional object being created and then immediately garbage collected. This is exactly the same as how the expression Just 0 >> Just 0 is the equivalent to Just 0, except again with an additional object being created and then garbage collected behind the scenes.</div><div><br></div><div>If you'd agree that Just 0 >> Just 0 ≡ Just 0, then I think you have to also agree that newIORef 0 >> newIORef 0 ≡ newIORef 0. In both cases, each side of the equivalence has the exact same semantics (save perhaps for additional allocations, which we generally ignore when doing this kind of analysis). No program which you could write could differentiate between the two sides (again, save by doing some trickery such as benchmarking the program and seeing which allocates more.)<br></div><div><br></div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Sun, Jun 3, 2018 at 6:56 PM Ivan Perez <<a href="mailto:ivanperezdominguez@gmail.com">ivanperezdominguez@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class="m_5307653312487399994gmail-im">
> This obeys law (1): (newIORef 0 >> newIORef 0) == newIORef 0.</span><br></div><div dir="ltr"><div><br>Doesn't this change the state in the IO monad (which is why (2) does not hold for this instance)? If so, would it still be true?<br></div></div><div dir="ltr"><div><br></div><div>Ivan<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 3 June 2018 at 07:55, Benjamin Fox <span dir="ltr"><<a href="mailto:foxbenjaminfox@gmail.com" target="_blank">foxbenjaminfox@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Here, as in general in the definitions of laws, the relevent question is referential transparency, not Eq instances.<br><br></div><div>(You'll note that generally in the definitions of laws the symbol "=" is used, not "==". Sometimes that's written as "≡", to be even clearer about what it represents, as for instance the <a href="https://wiki.haskell.org/Monad_laws" target="_blank">Monad Laws page</a> on the Haskell wiki does.)</div><div><br></div><div>For some laws, like the "fmap id = id" Functor law, this is obviously 
the only possible interpretation, as both sides of that equation are 
necessarily functions, and functions don't have an Eq instance.</div><div><br></div><div>So in this case, what the first law is asking for is that "ask >> ask" is the same as "ask", in that any instance of "ask" in a program can be replaced with "ask >> ask", or vice versa, without that changing the program's semantics.<br></div><div><br></div></div><div class="m_5307653312487399994HOEnZb"><div class="m_5307653312487399994h5"><br><div class="gmail_quote"><div dir="ltr">On Sun, Jun 3, 2018 at 9:47 AM Viktor Dukhovni <<a href="mailto:ietf-dane@dukhovni.org" target="_blank">ietf-dane@dukhovni.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
> On Jun 3, 2018, at 3:32 AM, Benjamin Fox <<a href="mailto:foxbenjaminfox@gmail.com" target="_blank">foxbenjaminfox@gmail.com</a>> wrote:<br>
> <br>
> Here is the counterexample:<br>
> <br>
> instance MonadReader (IORef Int) IO where<br>
>     ask = newIORef 0<br>
>     local _ = id<br>
> <br>
> This obeys law (1): (newIORef 0 >> newIORef 0) == newIORef 0.<br>
<br>
Can you explain what you mean?<br>
<br>
Prelude> :m + Data.IORef<br>
Prelude Data.IORef> let z = 0 :: Int<br>
Prelude Data.IORef> a <- newIORef z<br>
Prelude Data.IORef> b <- newIORef z<br>
Prelude Data.IORef> let c = newIORef z<br>
Prelude Data.IORef> let d = newIORef z<br>
Prelude Data.IORef> a == b<br>
False<br>
Prelude Data.IORef> c == d<br>
<br>
<interactive>:8:1: error:<br>
    • No instance for (Eq (IO (IORef Int))) arising from a use of ‘==’<br>
    • In the expression: c == d<br>
      In an equation for ‘it’: it = c == d<br>
<br>
-- <br>
        Viktor.<br>
<br>
_______________________________________________<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" 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><br>_______________________________________________<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" 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.<br></blockquote></div><br></div>
</blockquote></div>