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

Reply via email to