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
| > 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
| 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"
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
| > I think it is sound to do so. The advantage would be that newIORef
| > newSTRef would be the same (newRef, perhaps); ditto readRef,
| > 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
| 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
| > 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
| > stToIO :: ST IORegion a -> IO a
| It's more a matter of making IORegion work a bit harder since we have
| put it in the interface anyway.
More information about the Libraries