RealWorld

Ross Paterson ross at soi.city.ac.uk
Thu Sep 25 16:22:20 EDT 2003


On Thu, Sep 25, 2003 at 02:30:45PM +0100, Simon Peyton-Jones wrote:
> Ross Paterson writes:
> | The proposal is to expose
> | 
> | 	type IORef = STRef IORegion
> | 	type IOArray = STArray IORegion
> | 	type IOUArray = STUArray IORegion
> | 
> | (modulo the name of IORegion) but to keep IO opaque.  I think that while
> | IO includes state, it is not itself a state monad (because the "state"
> | there can be changed by other agents at the same time).

(where IORegion occurs in stToIO :: ST IORegion a -> IO a to make it safe)

> Aha. I hadn't realised that you want to expose IORef as an STRef, but
> not the IO monad itself. 
> 
> I certainly don't object to that, but I'm not sure of all the
> implications.  For example, at the moment one could have
> 	class MRef m r | m -> r, r -> m where
> 	  new :: a -> m (r a)
> 	  read :: r a -> m a
> 	  write :: r a -> a -> m ()
> 
> 	instance MRef IO IORef where ...
> 	instance MRef (ST s) (STRef s) where ...
> 
> I don't think that'll be legal if IORef = STRef IORegion, because the
> "r->m" dependency becomes ambiguous.  So we'd have to lose the "r->m"
> dependency.

The reason for having an MRef class was that there were two reference
types.  If there's only one, but parameterized by region, you might as
well parameterize on the region instead, describing a class of monads
that contain a heap region:

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

Then you can't have the s->m dependency:

	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 IORegion IO where
		liftST = Control.Monad.ST.stToIO
	instance MonadST s m => MonadST s (ContT r m) where
		liftST = lift . liftST
	...

but you don't want it: you want to manipulate the same references in
different monads (as we already do with the lazy and strict ST monads).
All the operations lift to all such monads, e.g.

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

and that handles arrays as well as refs.


More information about the Libraries mailing list