Reference types

Ashley Yakeley
Wed, 6 Feb 2002 01:26:56 -0800

At 2002-02-06 01:09, John Hughes wrote:

>No no no! This still makes the reference type depend on the monad type, which
>means that I cannot manipulate the same reference in two different monads! 

Yes you can. Consider:

    -- 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 -> Ref (ST s) a;
    newSTLiftedRef :: (LiftedMonad (ST s) m) => a -> Ref m a;
    newSTLiftedRef = liftRef . newSTRef;

With me so far? Now here's the clever bit: Refs created with 
newSTLiftedRef are of type '(LiftedMonad (ST s) m) => Ref m a'. This 
means they will work equally well as 'Ref (ST s) a' as they will as 'Ref 
TransformedMonad a'.

Ashley Yakeley, Seattle WA