Oh, sweet beans.&nbsp; I hadn&#39;t planned to incorporate mutable references -- my code uses them highly infrequently -- but I suppose that since mutable references are really equivalent to single-threadedness where referential transparency is concerned, that could be pulled off -- I would still want a StateThread associated type,&nbsp; but that&#39;d just be RealWorld for IO and STM, I guess.<br>
<br clear="all">Louis Wasserman<br><a href="mailto:wasserman.louis@gmail.com">wasserman.louis@gmail.com</a><br>
<br><br><div class="gmail_quote">On Thu, Feb 19, 2009 at 2:40 PM, Ryan Ingram <span dir="ltr">&lt;<a href="mailto:ryani.spam@gmail.com">ryani.spam@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;">
So, why not use this definition? &nbsp;Is there something special about ST<br>
you are trying to preserve?<br>
<br>
-- minimal complete definition:<br>
-- Ref, newRef, and either modifyRef or both readRef and writeRef.<br>
class Monad m =&gt; MonadRef m where<br>
 &nbsp; &nbsp;type Ref m :: * -&gt; *<br>
 &nbsp; &nbsp;newRef :: a -&gt; m (Ref m a)<br>
 &nbsp; &nbsp;readRef :: Ref m a -&gt; m a<br>
 &nbsp; &nbsp;writeRef :: Ref m a -&gt; a -&gt; m ()<br>
 &nbsp; &nbsp;modifyRef :: Ref m a -&gt; (a -&gt; a) -&gt; m a -- returns old value<br>
<br>
 &nbsp; &nbsp;readRef r = modifyRef r id<br>
 &nbsp; &nbsp;writeRef r a = modifyRef r (const a) &gt;&gt; return ()<br>
 &nbsp; &nbsp;modifyRef r f = do<br>
 &nbsp; &nbsp; &nbsp; &nbsp;a &lt;- readRef r<br>
 &nbsp; &nbsp; &nbsp; &nbsp;writeRef r (f a)<br>
 &nbsp; &nbsp; &nbsp; &nbsp;return a<br>
<br>
instance MonadRef (ST s) where<br>
 &nbsp; &nbsp;type Ref (ST s) = STRef s<br>
 &nbsp; &nbsp;newRef = newSTRef<br>
 &nbsp; &nbsp;readRef = readSTRef<br>
 &nbsp; &nbsp;writeRef = writeSTRef<br>
<br>
instance MonadRef IO where<br>
 &nbsp; &nbsp;type Ref IO = IORef<br>
 &nbsp; &nbsp;newRef = newIORef<br>
 &nbsp; &nbsp;readRef = readIORef<br>
 &nbsp; &nbsp;writeRef = writeIORef<br>
<br>
instance MonadRef STM where<br>
 &nbsp; &nbsp;type Ref STM = TVar<br>
 &nbsp; &nbsp;newRef = newTVar<br>
 &nbsp; &nbsp;readRef = readTVar<br>
 &nbsp; &nbsp;writeRef = writeTVar<br>
<br>
Then you get to lift all of the above into a monad transformer stack, MTL-style:<br>
<br>
instance MonadRef m =&gt; MonadRef (StateT s m) where<br>
 &nbsp; &nbsp;type Ref (StateT s m) = Ref m<br>
 &nbsp; &nbsp;newRef = lift . newRef<br>
 &nbsp; &nbsp;readRef = lift . readRef<br>
 &nbsp; &nbsp;writeRef r = lift . writeRef r<br>
<br>
and so on, and the mention of the state thread type in your code is<br>
just gone, hidden inside Ref m. &nbsp;It&#39;s still there in the type of the<br>
monad; you can&#39;t avoid that:<br>
<br>
newtype MyMonad s a = MyMonad { runMyMonad :: StateT Int (ST s) a }<br>
deriving (Monad, MonadState, MonadRef)<br>
<br>
But code that relies on MonadRef runs just as happily in STM, or IO,<br>
as it does in ST.<br>
<br>
 &nbsp;-- ryan<br>
<br>
2009/2/19 Louis Wasserman &lt;<a href="mailto:wasserman.louis@gmail.com">wasserman.louis@gmail.com</a>&gt;:<br>
<div><div></div><div class="Wj3C7c">&gt; It does. &nbsp;In the most recent version, the full class declaration runs<br>
&gt;<br>
&gt; class MonadST m where<br>
&gt; type StateThread m<br>
&gt; liftST :: ST (StateThread m) a -&gt; m a<br>
&gt;<br>
&gt; and the StateThread propagates accordingly.<br>
&gt;<br>
&gt; Louis Wasserman<br>
&gt; <a href="mailto:wasserman.louis@gmail.com">wasserman.louis@gmail.com</a><br>
&gt;<br>
&gt;<br>
&gt; On Thu, Feb 19, 2009 at 2:10 AM, Sittampalam, Ganesh<br>
&gt; &lt;<a href="mailto:ganesh.sittampalam@credit-suisse.com">ganesh.sittampalam@credit-suisse.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Henning Thielemann wrote:<br>
&gt;&gt; &gt; On Mon, 16 Feb 2009, Louis Wasserman wrote:<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; Overnight I had the following thought, which I think could work<br>
&gt;&gt; &gt;&gt; rather well. &nbsp;The most basic implementation of the idea is as<br>
&gt;&gt; &gt;&gt; follows:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; class MonadST s m | m -&gt; s where<br>
&gt;&gt; &gt;&gt; liftST :: ST s a -&gt; m a<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; instance MonadST s (ST s) where ...<br>
&gt;&gt; &gt;&gt; instance MonadST s m =&gt; MonadST ...<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Like MonadIO, isn&#39;t it?<br>
&gt;&gt;<br>
&gt;&gt; I think it should be, except that you need to track &#39;s&#39; somewhere.<br>
&gt;&gt;<br>
&gt;&gt; Ganesh<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; ==============================================================================<br>
&gt;&gt; Please access the attached hyperlink for an important electronic<br>
&gt;&gt; communications disclaimer:<br>
&gt;&gt;<br>
&gt;&gt; <a href="http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html" target="_blank">http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html</a><br>
&gt;&gt;<br>
&gt;&gt; ==============================================================================<br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
</div></div><div><div></div><div class="Wj3C7c">&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>
&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br>