Typesafe MRef with a regular monad
Ashley Yakeley
ashley@semantic.org
Wed, 04 Jun 2003 15:19:53 -0700
In article <200306042005.h54K5mG0014203@adric.fnmoc.navy.mil>,
oleg@pobox.com wrote:
> Ashley Yakeley wrote:
> ] ] Is it possible to actually implement a working instance of RefMonad in
> ] ] Haskell, without making use of a built-in monad like IO or ST?
>
> ] You certainly wouldn't be able to do this for any monad M which had:
>
> ] performM :: forall a. M a -> a;
>
> ] ...because it wouldn't be type-safe: you'd be able to construct coerce
> ] :: a -> b just as you can with unsafePerformIO.
>
> Fortunately, that doesn't seem to be the case.
That's only because you've failed to do the difficult part: implement
newRef. Your monadic solution has a statically typed/sized store: I'd
say it doesn't properly count as a "heap" since you can't heap new stuff
on it.
The original problem was to create an instance of
class Monad m => RefMonad m r | m -> r where
newRef :: a -> m (r a)
readRef :: r a -> m a
writeRef :: r a -> a -> m ()
without making use of IO or ST. Given some M and R that have
instance RefMonad M R
performM :: forall a. M a -> a
one can write this:
coerce :: forall a b. a -> b;
coerce a = let
{
ref = performM (newRef Nothing);
} in performM (do
{
writeRef ref (Just a);
mb <- readRef ref;
case mb of {Just b -> return b;};
});
--
Ashley Yakeley, Seattle WA