RealWorld

Simon Peyton-Jones simonpj at microsoft.com
Thu Sep 25 15:30:45 EDT 2003



| -----Original Message-----
| From: Ross Paterson [mailto:ross at soi.city.ac.uk]
| Sent: 18 September 2003 10:20
| To: Simon Peyton-Jones
| Cc: Alastair Reid; Simon Marlow; libraries at haskell.org
| Subject: Re: RealWorld
| 
| 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).

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.

Maybe that's ok.  (I don't think MRef currently exists in the
libraries.)  But it's an example of a consequence of the choice you
suggest.

Simon

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