At 2002-02-06 03:38, John Hughes wrote:
Well, I'm still not convinced. A reference *value* can't have the type
(LiftedMonad (ST s) m) => Ref m a
Oh, yeah, you're right. I made a mistake here: newSTRef :: a -> Ref (ST s) a; newSTLiftedRef :: (LiftedMonad (ST s) m) => a -> Ref m a; This should of course be: newSTRef :: a -> (ST s) (Ref (ST s) a); newSTLiftedRef :: (LiftedMonad (ST s) m) => a -> m (Ref m a); ...which won't help, because the Ref will only work in the monad that created it. But 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.
Are you really in Seattle? If so, you must be a real nightbird or a tremendously early riser!
Um, yeah, that's a side effect of unemployment, along with haemorrhaging open-source software (see Truth). Does anyone need a Haskell developer in the greater Seattle area? -- Ashley Yakeley, Seattle WA