
Sven Panne wrote:
Huh? I'm not sure what you mean exactly, but with the help of unsafePerformIO and a pragma for clever compilers you can simulate something like a global variable in Haskell. Here an excerpt from the GLUT menu handling module:
{-# NOINLINE theMenuTable #-} theMenuTable :: IORef MenuTable theMenuTable = unsafePerformIO (newIORef emptyMenuTable) ...
Definitely not something to be proud of, but quite handy from time to time. :-) Alternatives are passing the IORef to every function which needs it (but this would clutter up the GLUT API in the above case) or using the FFI for holding global data on the C side. GHC uses a similar hack internally, too, BTW.
This is not just handy from time to time, but very frequently. I've just discovered it occurs about 100 times in 100K LOC that I am responsible for, so often that I have stopped feeling guilty about it. I don't really know what else I could do. One solution would be to use implicit parameters to pass a global state variable around, but this would require me to change the type of huge numbers of functions, since implicit parameters are still explicit in types. I don't remember having any actual bugs caused by unsafePerformIO. Well, only one, before I knew about putting NOINLINE in.
participants (1)
-
George Russell