Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8142595
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T12:51:56+00:00 2026-06-06T12:51:56+00:00

In main I can read my config file, and supply it as runReader (somefunc)

  • 0

In main I can read my config file, and supply it as runReader (somefunc) myEnv just fine. But somefunc doesn’t need access to the myEnv the reader supplies, nor do the next couple in the chain. The function that needs something from myEnv is a tiny leaf function.

How do I get access to the environment in a function without tagging all the intervening functions as (Reader Env)? That can’t be right because otherwise you’d just pass myEnv around in the first place. And passing unused parameters through multiple levels of functions is just ugly (isn’t it?).

There are plenty of examples I can find on the net but they all seem to have only one level between runReader and accessing the environment.


I’m accepting Chris Taylor’s because it’s the most thorough and I can see it being useful to others. Thanks too to Heatsink who was the only one who attempted to actually directly answer my question.

For the test app in question I’ll probably just ditch the Reader altogether and pass the environment around. It doesn’t buy me anything.

I must say I’m still puzzled by the idea that providing static data to function h changes not only its type signature but also those of g which calls it and f which calls g. All this even though the actual types and computations involved are unchanged. It seems like implementation details are leaking all over the code for no real benefit.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T12:51:57+00:00Added an answer on June 6, 2026 at 12:51 pm

    You do give everything the return type of Reader Env a, although this isn’t as bad as you think. The reason that everything needs this tag is that if f depends on the environment:

    type Env = Int
    
    f :: Int -> Reader Int Int
    f x = do
      env <- ask
      return (x + env)
    

    and g calls f:

    g x = do
      y <- f x
      return (x + y)
    

    then g also depends on the environment – the value bound in the line y <- f x can be different, depending on what environment is passed in, so the appropriate type for g is

    g :: Int -> Reader Int Int
    

    This is actually a good thing! The type system is forcing you to explicitly recognise the places where your functions depend on the global environment. You can save yourself some typing pain by defining a shortcut for the phrase Reader Int:

    type Global = Reader Int
    

    so that now your type annotations are:

    f, g :: Int -> Global Int
    

    which is a little more readable.


    The alternative to this is to explicitly pass the environment around to all of your functions:

    f :: Env -> Int -> Int
    f env x = x + env
    
    g :: Env -> Int -> Int
    g x = x + (f env x)
    

    This can work, and in fact syntax-wise it’s not any worse than using the Reader monad. The difficulty comes when you want to extend the semantics. Say you also depend on having an updatable state of type Int which counts function applications. Now you have to change your functions to:

    type Counter = Int
    
    f :: Env -> Counter -> Int -> (Int, Counter)
    f env counter x = (x + env, counter + 1)
    
    g :: Env -> Counter -> Int -> (Int, Counter)
    g env counter x = let (y, newcounter) = f env counter x
                      in (x + y, newcounter + 1)
    

    which is decidedly less pleasant. On the other hand, if we are taking the monadic approach, we simply redefine

    type Global = ReaderT Env (State Counter)
    

    The old definitions of f and g continue to work without any trouble. To update them to have application-counting semantics, we simply change them to

    f :: Int -> Global Int
    f x = do
      modify (+1)
      env <- ask
      return (x + env)
    
    g :: Int -> Global Int
    g x = do
      modify(+1)
      y <- f x
      return (x + y)
    

    and they now work perfectly. Compare the two methods:

    • Explicitly passing the environment and state required a complete rewrite when we wanted to add new functionality to our program.

    • Using a monadic interface required a change of three lines – and the program continued to work even after we had changed the first line, meaning that we could do the refactoring incrementally (and test it after each change) which reduces the likelihood that the refactor introduces new bugs.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

i need a link where i can read and understand the main standards to
Can't understand what is a problem here: I have got main.cpp file where I
I have a config file, in etc/ called 1.conf Here is the contents.. [2-main]
Trying to read into an object the following XML file (can be changed) into
Normally, one can specify a service binding using the app.config file, and the system
I need to write a PHP or javascript that can read the clickbank cookie
I have the following: config = ConfigParser() config.read('connections.cfg') sections = config.sections() How can I
I am writing code that read customized config section from app.config, but I get
Is there a simple way to read from the global application.exe.config file from a
I have an image $(#main) how can I use jquery to dosomething(this) when the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.