Dealing with configuration data

Koen Claessen
Thu, 26 Sep 2002 08:47:56 +0200 (MET DST)

Hal Daume III suggested:

 | data Configuration = ...  -- config data
 | globalConfig :: IORef Configuration
 | globalConfig = unsafePerformIO (newIORef undefined)
 | getConfig :: Configuration
 | getConfig = unsafePerformIO $ readIORef globalConfig
 | main = do
 | configuration from calls to getConfig...
 |    writeIORef globalConfig configuration
 |    doStuff
 |    return ()

In this case, there is no need to use unsafePerformIO more
than once, nor does one need IORefs. Here is how:

  data Configuration = ...  -- config data

  getConfig :: Configuration
  getConfig = unsafePerformIO $
    do configuration from file...
       return configuration

  main =
    do doStuff

We know getConfig will only be evaluated once (because of
sharing) (*)

Don't use the dirty stuff when you do not have to! :-)

I think GHC even supports a function getArgs which is not in
the IO monad since the arguments to a program do not change
during a program. If getConfig only depends on the
arguments, no unsafePerformIO is necessary at all.

Gofer, and even early versions of Hugs, had a function
openFile ::  FilePath -> String. Thge rationale was (I
guess) that the contents of a file would not change during
the evaluation of a Gofer program.


(*) Actually, a Haskell compiler is free to inline these
kind of expressions, so really one has to give a
NOINLINE pragma to the compiler as well.

Koen Claessen
Chalmers University, Gothenburg, Sweden.