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 _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell