Reference types
John Hughes
rjmh@cs.chalmers.se
Thu, 7 Feb 2002 09:52:57 +0100 (MET)
I have a solution...
data Ref m a = MkRef
{
get :: m a,
set :: a -> m (),
modify :: (a -> a) -> m ()
};
-- m somehow uses 'rep' internally
class (Monad rep, Monad m) => LiftedMonad rep m where
{
lift :: rep a -> m a;
}
instance LiftedMonad (ST s) (ST s) where
{
lift = id;
}
instance LiftedMonad (ST s) TransformedMonad where
...
liftRef :: (LiftedMonad rep m) => Ref rep a -> Ref m a;
liftRef ref = ...
newSTRef :: a -> (ST s) (Ref (ST s) a);
getLifted :: (LiftedMonad rep m) => Ref rep a -> m a;
getLifted = get . liftRef;
setLifted :: (LiftedMonad rep m) => Ref rep a -> a -> m ();
setLifted = set . liftRef;
modifyLifted :: (LiftedMonad rep m) => Ref rep a -> (a -> a) -> m ();
modifyLifted = modify . liftRef;
Now when you need a new Ref, use newSTRef, and when you need to use the
Ref, use getLifted, setLifted and modifyLifted. They'll work equally well
with (ST s) as with TransformedMonad.
Hmm. Yes. But you still haven't addressed dropping references created in the
transformed monad back into the underlying one again. And this does seem to
be getting rather complicated and expensive... are you sure it's worth the
candle? I'm quite happy to have references depend on a state identifier myself.
John