[Haskell] Initialisation without unsafePerformIO

George Russell ger at informatik.uni-bremen.de
Tue Jun 1 12:06:36 EDT 2004


What ideas do people have for getting rid of unsafePerformIO?

The most common use of unsafePerformIO, for me at least, is initialisation.
There *surely* must be a better way of doing this, but I haven't really
seen much discussion of the topic.  Here is my back-of-the-envelope
suggestion for a new interface, can anyone do better?

> type Dict 
> -- a collection of initialised data.
> 
> register :: Typeable a => Dict -> a -> IO ()
> -- register a value of type (a) in the dictionary.  Only one value of each
> -- type is allowed in the dictionary; registering the same type twice will
> -- cause an exception.
> 
> defaultDict :: IO Dict
> -- Each Haskell "main" program will have one of these.
> 
> lookup :: Typeable a => Dict -> IO a
> -- Get the value of (a) registered in the Dict, or raise an exception if it
> -- isn't.

Thus, libraries which rely on internal initialised state will also have
to provide a function which initialises that state.  I don't think this is
very painful.  IME it's often required anyway, if you want to provide the
library with additional parameters.  Also the library could catch the
exception from (lookup) and give a helpful error message of the form
"You forgot to run Gadgets.initialise".

We can also provide additional dictionaries.

> thisThreadDict :: IO Dict
> 
> newEmptyDict :: IO Dict
> 
> runWithDifferentDefaultDict :: Dict -> IO a -> IO a

This would allow the programmer much more control over initialisation.
For example, programs distributed over a large number of processors are
no longer obliged to use a single global dictionary, which is effectively
what is required now.  (How else can you make sure that two processors do
not try to evaluate the same unsafePerformIO value at once?)  And
runWithDifferentDefaultDict allows you to change the value returned by
defaultDict during an action, meaning that programs can for example
initialise the same library multiple times, which would be useful during
debugging.

Well it's a start I think.  Can anyone do better?



More information about the Haskell mailing list