base package

Joachim Breitner mail at
Wed Feb 20 14:57:26 CET 2013


Am Freitag, den 15.02.2013, 23:00 +0100 schrieb Joachim Breitner:
> Am Freitag, den 15.02.2013, 14:50 +0000 schrieb Simon Marlow:
> > On 15/02/13 12:22, Joachim Breitner wrote:
> > > more progress: On top of base-pure, I created base-io involving GHC/IO
> > > and everything required to build it (which pulled in ST, some of Foreign
> > > and unfortunately some stuff related to Handles and Devices, because it
> > > is mentioned in IOException). This is the list of modules:
> > >
> >
> > You have a random collection of modules here :)
> > 
> > I think you want to have the IO *monad* (GHC.IO) live in a lower layer, 
> > separate from the IO *library* (GHC.IO.Device and so on).  Every Haskell 
> > implementation will need the IO monad, but they might want to replace 
> > the IO library with something else.
> > 
> > Things like GHC.IORef, GHC.MVar can all live in a low-down layer because 
> > they're just wrappers over the primops.
> Right, that is my aim, and I started with GHC.IO. But unfortunately, the
> IO monad calls failIO, which is an IOError which has a field of type
> ioe_handle :: Maybe Handle (and one of type CInt) which pulls in all the
> rest there, and so far I did not have a good idea how to untangle that.
> What would break if fail would not raise an IOError, but a separate
> exception type, e.g. IOFailError? Probably too much, as users expect to
> catch the exception raised by fail with an exception handler that
> matches IOError.

I’m still stuck at the problem of separating the definition of IO and
Monad IO from all file related stuff, which is prevented by the "Maybe
Handle" field in the IOError data type.

Given that IOError is abstract to the „regular“ user (i.e. not to
base-io-file), I guess we can afford to be a little bit hacky here. Two
ideas come to my mind:

1. Instead of declaring the field as "Maybe Handle", we define a
pseudo-handle datatype
        data NotYetAHandle = NotYetAHandle
and use "Maybe NotYetAHandle" in IOError, with the documented convention
that only code in base-io-file (and code further down the tree) may use
this field, and only after unsafeCoerce’ing it to a Maybe Handle. This
way, the base-io package does not have to include the definition, but
the IOError data type still has place for it.

If the NotYetAHandle constructor is not exported, and base-io-file
defines functions NotYetAHandle -> Handle and Handle -> NotYetAHandle
via unsafeCoerce, then the unsafeness is very local and nobody can break
the code without also using unsafeCoerce.

2. A little safer (and with a little more overhead) wold be to include
Data.Dynamic in base and change the field to a "Maybe Dynamic". Same
procedure as above, only that a violation of the convention might be
caught without crashes.

Is having a package that provides io without providing file-related
definition worth this kludge?


Joachim "nomeata" Breitner
Debian Developer
  nomeata at | ICQ# 74513189 | GPG-Keyid: 4743206C
  JID: nomeata at |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <>

More information about the Glasgow-haskell-users mailing list