RealWorld

Ross Paterson ross@soi.city.ac.uk
Mon, 8 Sep 2003 10:52:51 +0100


I wrote:
> Now that RealWorld, formerly an implementation trick inside GHC, has
> become part of the public interface:
> 
> 	stToIO :: ST RealWorld a -> IO a
> 
> (to make stToIO sound), I think it needs a better name.  The IO monad
> does not in fact give you exclusive access to the world, but to a
> region of the heap separate from those used by invocations of runST.
> (That's not all IO does, of course, but it's the relevant part for
> stToIO.)  I propose IORegion.

On Fri, Sep 05, 2003 at 02:54:55PM +0100, Simon Peyton-Jones wrote:
> Would be fine with me.

On reflection, IORegion sounds a bit operational; perhaps IOState is
better (though I see the name is used in HOpenGL for something else).

More suggestions:

1) Pursuing the view that this thing identifies a special ST-style
state included in the IO monad, we could view the IO state stuff as
a special case of the ST stuff, changing

	newtype IORef a = IORef (STRef IOState a)
	newtype IOArray i e = IOArray (STArray IOState i e)
	newtype IOUArray i e = IOUArray (STUArray RealWorld i e)

(currently exported opaquely) to

	type IORef = STRef IOState
	type IOArray = STArray IOState
	type IOUArray = STUArray IOState

so that there would only be one type of reference.

2) For additional genericity, define a class

	class MonadST s m | m -> s where
		liftST :: Control.Monad.ST.ST s a -> m a

with instances

	instance MonadST s (Control.Monad.ST.ST s) where
		liftST = id
	instance MonadST s (Control.Monad.ST.Lazy.ST s) where
		liftST = strictToLazyST
	instance MonadST IOState IO where
		liftST = stToIO
	instance MonadST s m => MonadST s (ContT r m) where
		liftST = lift . liftST
	...

then all the operations lift to all such monads, e.g.

	readSTRef :: MonadST s m => STRef s a -> m a
	readSTRef r = liftST (Data.STRef.readSTRef r)

The instantiations for Control.Monad.ST.Lazy.ST and IO are identical
to the existing definitions of Data.STRef.Lazy.readSTRef and readIORef
respectively, and similarly for other operations, arrays, etc.

This class would need to be in base, to permit

	instance MonadST s m => MArray (STArray s) e m
	instance MonadST s m => MArray (STUArray s) Bool m
	etc

I recall that you proposed a RefMonad class on the haskell list in Feb
2002, but the problem there was that references were tied to a monad,
rather than the state within the monad.