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