I have a module where a global environment (defining certain constraints such as neighbor IP addresses, etc.) is created and initialized by calling an initializing function. A number of subsequent functions should use these constraints when they are called.
Whilst in principle I understand what the reader monad does I am not quite sure how I can apply this to my problem, esp.
-
How it can be used to initialize an environment that is defined by the user and passed as data/arguments to the initializing function. I mean, the reader monad has to get the actual values that make up the global immutable environment from somewhere. I would like that the values are read from an initializing function call like
myinitial :: arg1 -> arg1 -> IOStringwhere subsequentlyarg1andarg2become global immutable data accessible to subsequent functions via the reader monad(?) -
How I can use these environment values as function arguments e.g.
recvFrom s arg1wherearg1is global immutable data from my environment. Orif arg2 > arg1 then ... else ...
I could make a configuration file of course, but I feel that a configuration file will take away to much flexibility.
[Edit] I understand about ask, but shouldn’t there be additional “pointfree-like” ways so that the global/environment immutable can be omitted if the function signature has been defined right? How would I i.e. need to refactor my if-then-else to apply this.
Here’s an example that may clear things up. First you need to import the Reader module:
Now let’s define some data structure (that we’re going to use to hold a name and an age)
Now define a function that works in the Reader monad (it’s type is
Reader Config (String, Int)but we don’t need to specify that – it can be inferred). All this function does is ask for the environment (of typeConfig) and then extracts the fields and does something with them.Now we put it all together into a program. The first four lines after the do block allow the user to enter their name and age. Then we build a
Configstructure using the user’s inputs (we have to usereadto convert the variable_age, which is aString, into anIntso that we can feed it to theConfigconstructor) and executeexamplewith this environment, using therunReaderfunction. Finally, we use the result of this computation to generate some output.