Global Variables and Monad Reader

I have a module where a global environment (defining certain restrictions, such as neighboring IP addresses, etc.) is created and initialized by calling the initialization function. A number of subsequent functions should use these restrictions when calling them.

While in principle I understand what the monad is reading, I'm not quite sure how I can apply this to my problem, especially.

  • How can it be used to initialize an environment that is defined by the user and passed as data / arguments to the initialization function. I mean, the reader monad must get from somewhere the actual values ​​that make up the global immutable environment. I would like the values ​​to be read from a call to an initialization function of the type myinitial :: arg1 -> arg1 -> IOStringwhere later arg1they arg2become global immutable data, accessible to subsequent functions using the reader monad (?)

  • How can I use these environment values ​​as function arguments, for example. recvFrom s arg1where arg1is the global immutable data from my environment. Orif arg2 > arg1 then ... else ...

I could make a configuration file, of course, but I feel that the configuration file takes up a lot of flexibility.

[Change] I understand the demand, but should additional “point” methods not appear so that the global / environment immutable could be omitted if the function signature was correctly defined? How would I need to reorganize my if-then-else to apply this .

+5
source share
2 answers

Here is an example that can clarify the situation. First you need to import the Reader module:

import Control.Monad.Reader

Now let's define some data structure (which we are going to use to store the name and age)

data Config = Config { name :: String, age :: Int }

, ( Reader Config (String, Int), , ). ( Config), -.

example = do
    c <- ask
    return ("Hello " ++ name c, 2 * age c)

. do . Config, ( read, _age, String, Int, Config) example , runReader. , .

main = do
    putStrLn "Enter your name:"
    _name <- getLine
    putStrLn "Enter your age:"
    _age <- getLine
    let config = Config _name (read _age)
    let result = runReader example config
    putStrLn $ fst result
    putStrLn $ "Twice your age is: " ++ show (snd result)
+4

, ask runReader.

ask:

ask :: Reader m r => m r

, . , , , :

do x <- ask
   recvFrom s x

( recvFrom, )

runReader, , . Reader, , :

runReader :: Reader r a -> r -> a

: ( ) r ( ). , , 1- , a. :

result = runReader computationUsingArg1Arg2 (arg1, arg2)

Then, inside computationUsingArg1Arg2you can read arg1and arg2through ask.

+5
source

All Articles