Ross Paterson ross at
Thu Sep 18 11:19:48 EDT 2003

On Thu, Sep 18, 2003 at 08:56:40AM +0100, Simon Peyton-Jones wrote:
> Is the proposal that the library design exposes to the programmer the
> following type synonyms:
> 	type IO a = ST IORegion a
> 	type IORef a = STRef IORegion a

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).

> I think it is sound to do so.  The advantage would be that newIORef and
> newSTRef would be the same (newRef, perhaps); ditto readRef, writeRef
> etc.

If IO is opaque, then we have

	newIORef = stToIO . newSTRef

etc.  It's not quite as generic as your version, but it is a conceptual
simplification, and it does allow generic classes like

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

with instances for IO, both ST's and various constructed monads, so we
could have the likes of

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

My problem with exposing the GHC implementation of IO is that I don't
think it's the Truth, and Haskell has a record of punishing untruths
sooner or later.

> I think this would be fine for GHC.  It might not be fine for Hugs
> because they implement IO and ST differently I think.  No idea about
> NHC.

NHC doesn't have ST (rank-2 types).  In Hugs, they are now

	newtype IO a = IO ((a -> IOResult) -> IOResult)
	newtype ST s a = ST (forall r. (a -> r) -> r)

	primitive newIORef   "newRef" :: a -> IO (IORef a)
	primitive newSTRef   "newRef" :: a -> ST s (STRef s a)

But I'm not proposing that this be exposed.

> Or, alternatively, is the question something to do with the internals of
> the library, of interest to implementers but not to users of the
> library?  Or is it just to do with the type of stToIO, which should be
> 	stToIO :: ST IORegion a -> IO a

It's more a matter of making IORegion work a bit harder since we have to
put it in the interface anyway.

More information about the Libraries mailing list