Dealing with configuration data
Koen Claessen
koen@cs.chalmers.se
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
| ...read configuration from file...no 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 ...read 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.
Regards,
/Koen.
(*) 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
http://www.cs.chalmers.se/~koen
Chalmers University, Gothenburg, Sweden.