I often find this pattern in Haskell code:
options :: MVar OptionRecord
options = unsafePerformIO $ newEmptyMVar
...
doSomething :: Foo -> Bar
doSomething = unsafePerformIO $ do
opt <- readMVar options
doSomething' where ...
Basically, one has a record of options or something similar, that is initially set at the program's beginning. As the programmer is lazy, he doesn't want to carry the options
record all over the program. He defines an MVar
to keep it - defined by an ugly use of unsafePerformIO
. The programmer ensures, that the state is set only once and before any operation has taken place. Now each part of the program has to use unsafePerformIO
again, just to extract the options.
In my opinion, such a variable is considered pragmatically pure (don't beat me). Is there a library that abstracts this concept away and ensures that the variable is set only once, i.e. that no call is done before that initialization and that one doesn't have to write unsafeFireZeMissilesAndMakeYourCodeUglyAnd
DisgustingBecauseOfThisLongFunctionName
unsafePerformIO
in top-level bindings for certain limited kinds of initialization I can imagine, like creating anIORef
. Top level bindings doing arbitraryIO
wouldn't surprise me, but it seems unwise. UsingunsafePerformIO
to read bits of potentially mutable data from inside assorted functions is just ridiculous. – Roselynroseman