I often need to make a core function that’s used in many places somehow configurable – i.e., it may use either algorithm A or algorithm B depending on a command-line switch; or have it print extra-verbose information to stdout if a ‘debug’ flag is set somehow.
How should I implement such global flags?
I see 4 options, all of them aren’t really good.
-
Read command-line arguments from the function – bad, because that needs IO monad and the core calculation functions all are pure, I don’t want to get IO in there;
-
Pass a parameter from main/IO all the way through to the ‘leaf’ function which needs to change behavior – completely unusable, as that means changing a dozen of unrelated functions in different modules to pass this parameter, and I want to try out such configuration options multiple times without changing the wrapping code every time;
-
Use
unsafePerformIOto get a true global variable – feels ugly and overkill for such a simple issue; -
Right in the middle of the function have code for both options and comment one of them out. Or have functions do_stuff_A and do_stuff_B, and change which one of them is called depending on what a global function
needDebugInfo=Truesays. That’s what I’m doing now for thedebuginfo, but it can’t be changed w/o recompile, and it shouldn’t really be the best available way…
I don’t need or want global mutable state – I want to have a simple global flag that’s immutable at runtime but can be somehow set when the program is launched. Are there any options ?
Our new HFlags library is exactly for this.
If you would like to see an example usage like your example, look into this:
https://github.com/errge/hflags/blob/master/examples/ImportExample.hs
https://github.com/errge/hflags/blob/master/examples/X/B.hs
https://github.com/errge/hflags/blob/master/examples/X/Y_Y/A.hs
No kind of parameter passing is needed between the modules, and you can define new flags with an easy syntax. It uses unsafePerformIO internally, but we think that it does that in a safe way, and you won’t have to concern yourself with that.
There is a blog post about this stuff at: http://blog.risko.hu/2012/04/ann-hflags-0.html