On Wed, 04 Jun 2003 15:19:53 -0700 Ashley Yakeley <[EMAIL PROTECTED]> wrote:
> In article <[EMAIL PROTECTED]>, > [EMAIL PROTECTED] 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. I agree, if I knew I'd have 5 components before I could just use a 5 tuple and a State monad. I'd have to look back over the other heap stuff to see what it provides type-wise, but (at least the "new" monad version) seems to miss the point. > 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 M = (forall s.ST s) R = STRef s e.g. runST :: (forall s.ST s a) -> a you can use the same trick for your own RefMonad. I'm not sure if this will work with RefMonad exactly. If ST/STRef can be made an instance of RefMonad without any trouble though, then I believe it should work. > 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;}; > }); I was having fun with coerce :: a -> b coerce x = unsafePerformIO (writeIORef ref x >> readIORef ref) where ref = unsafePerformIO (newIORef undefined) last night, some fun examples (using GHCi 5.04.3), data Foo a = Bar | Baz a (Foo a) coerce 5 :: Maybe Int ==> Nothing coerce 'a' :: Int ==> 97 coerce [1..3] :: Foo Integer ==> (Baz 1 (Baz 2 (Baz 3 Bar))) coerce [4] :: Maybe Integer ==> Just 4 I need to reread the GHC internals paper, I want to see if I can get one like (coerce something :: (sometype -> someothertype)) someotherthing _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell