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
unsafePerformIO
to 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=True
says. 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 ?