more unsafePerformIO questions (is it safe to use with ReadMode Handles)?

Simon Marlow simonmar@microsoft.com
Tue, 19 Aug 2003 10:27:23 +0100


=20
> I'm finishing up my Haskell interface to WordNet
> (http://www.cogsci.princeton.edu/~wn/) and have a standard
> unsafePerformIO question :).
>=20
> Basically, the interface functions by first calling an initialization
> function, 'initializeWordNet :: IO WordNetEnv'.  WordNetEnv is
> essentially just a record of a lot of Handles which we will be reading
> from and doing binary search in.
>=20
> All the functions which use the WordNetEnv (i.e., every other function
> in the interface) basically do the following:
>=20
>   - take one handle from the WordNetEnv and do binary search=20
>     in it, read a line.
>=20
>   - use that line to read another line from another of the handles
>=20
>   - parse that last one
>=20
> of course, therefore, all of these functions have type '... -> IO
> something'.
>=20
> However, one of the "rules of thumb" for using unsafePerformIO is when
> you can imagine a functional interface doing the same thing.  I can:
> simply read in all the databases in initializeWordNet and then do
> Data.List.lookup on the results.  Does this mean it's safe to wrap all
> these functions in unsafePerformIO?

It sounds like your interface is pure, as long as you don't expect the
contents of any of the databases to change during the run of your
program.  That is, it doesn't matter whether you do all the IO at the
start or lazilly on demand.

If the databases *do* change over time, then there are two
possibilities:

  1. the contents change due to external factors only
  2. the contents change because this program doing the writing

in (1), you can still pretend the interface is pure, by imagining that
all the changes happened earlier.  This works as long as you only read
the external data once.  In (2), you have a truly impure interface, so
using unsafePerformIO would be wrong.

Cheers,
	Simon