RE: [Haskell] IO == ST RealWorld
| Is there any reason why IO should not be defined as: | > type IO a = ST RealWorld a | in implementations that support ST? | | This way IORef/STRef and IOArray/STArray can be merged. I know under the | hood they already share code, but this way they can also share an interface. Indeed, this was the way we had it originally in GHC. It does seem like a good idea. We changed it for reasons that I know that we have forgotten, alas, because we tried to recall about a year ago. It's always possible that the original reasons for the change no longer apply. Perhaps someone can try it out? Simon
On Tue, 2006-01-24 at 09:17 +0000, Simon Peyton-Jones wrote:
| Is there any reason why IO should not be defined as: | > type IO a = ST RealWorld a | in implementations that support ST? | | This way IORef/STRef and IOArray/STArray can be merged. I know under the | hood they already share code, but this way they can also share an interface.
Indeed, this was the way we had it originally in GHC. It does seem like a good idea. We changed it for reasons that I know that we have forgotten, alas, because we tried to recall about a year ago. It's always possible that the original reasons for the change no longer apply.
Perhaps someone can try it out?
Is the reason for not having this type synonym maybe "bad type error messages"? In my program, I've got a type synonym just like that: type ExecM a = StateT FixpointState (ReaderT ProgReaderState IO) a When I erroneously give the simple function warn :: Context -> W.Warning -> ExecM () warn ctxt warn = do .... an extra argument in the type signature warn :: Context -> W.Warning -> Int -> ExecM () I get: Couldn't match `(->) Int' against `StateT FixpointState (ReaderT ProgReaderState IO)' Expected type: Int -> t Inferred type: ExecM () Even if you've defined the type synonym yourself, it takes a while to realise that the type synonym and the ExecM () are the same, in particular since the type variable t is omitted in the first part. There are many other places in the libraries which could do with a generalisation of types, but where similarly difficult type error messages will arise. One function that particularly annoyed me is in Control.Exception handle :: (Exception -> IO a) -> IO a -> IO a should be handle :: MonadIO m => (Exception -> m a) -> m a -> m a to be usable with my ExecM monad. liftIO doesn't really help here. If it weren't for the type error messages, I would suggest to generalise all function using IO a to MonadIO m => m a. Axel.
Axel Simon <A.Simon@kent.ac.uk> writes:
One function that particularly annoyed me is in Control.Exception
handle :: (Exception -> IO a) -> IO a -> IO a
should be
handle :: MonadIO m => (Exception -> m a) -> m a -> m a
I think it would be unimplementable. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
participants (3)
-
Axel Simon -
Marcin 'Qrczak' Kowalczyk -
Simon Peyton-Jones