[Haskell] IO == ST RealWorld

Axel Simon A.Simon at kent.ac.uk
Tue Jan 24 05:57:22 EST 2006

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'
        `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.


More information about the Haskell mailing list