# Reference types

**Ashley Yakeley
**
ashley@semantic.org

*Tue, 5 Feb 2002 16:54:33 -0800*

At 2002-02-05 15:10, John Hughes wrote:
>*Oh no, please don't do this! I use the RefMonad class, but *without* the
*>*dependency r -> m. Why not? Because I want to manipulate (for example) STRefs
*>*in monads built on top of the ST monad via monad transformers. So I use the
*>*same reference type with *many different* monads! Your change would make this
*>*impossible.
*
I don't think so. Provided you have a class that represents your monads,
I don't see why you can't do this:
class (Monad m) => MyMonad m where
...
myIntRef :: (MyMonad m) => Ref m Int;
...except that with Simon's suggested change you wouldn't be able to
define your own Refs. I believe the best solution to the problem involves
leaving the existing functions as is but adding something like this:
data Ref m a = MkRef
{
get :: m a,
set :: a -> m (),
modify :: (a -> a) -> m ()
};
mkRef g s = MkRef g s (\map -> do
{
val <- g;
s (map val);
});
refBind :: (Monad m) => (m a) -> (a -> Ref m b) -> Ref m b;
refBind ma arb = MkRef
( ma >>= (\a -> get (arb a) ))
(\b -> ma >>= (\a -> set (arb a) b ))
(\map -> ma >>= (\a -> modify (arb a) map ));
class (Monad m) => RefMonad m where
{
newRef :: a -> m (Ref m a); -- "standard" ref for this monad
};
instance RefMonad IO where
{
newRef a = do
{
r <- newIORef a;
return MkRef (readIORef r) (writeIORef r) (modifyIORef r)
};
};
instance RefMonad (ST s) where
etc.
The point is that the m -> r dependency is also unnecessary, except when
you want a new "standard" ref for a monad.
--
Ashley Yakeley, Seattle WA