Reference types
Ashley Yakeley
ashley@semantic.org
Wed, 6 Feb 2002 15:35:05 -0800
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