Before getting to your main question about `Reader`

, I will start with a few remarks about applicative-versus-monad in general. While this applicative style expression...

```
g <$> fa <*> fb
```

... is indeed equivalent to this do-block...

```
do
x <- fa
y <- fb
return (g x y)
```

... switching from `Applicative`

to `Monad`

makes it possible to make decisions about which computations to perform based on results of other computations, or, in other words, to have effects that depend on previous results (see also chepner's answer):

```
do
x <- fa
y <- if x >= 0 then fb else fc
return (g x y)
```

While `Monad`

is more powerful than `Applicative`

, I suggest not thinking of it as if one were more useful than the other. Firstly, because there are applicative functors that aren't monads; secondly, because not using more power than you actually need tends to make things simpler overall. (In addition, such simplicity can sometimes bring tangible benefits, such as an easier time dealing with concurrency.)

A parenthetical note: when it comes to applicative-versus-monad, `Reader`

is a special case, in that the `Applicative`

and `Monad`

instances happen to be equivalent. For the function functor (that is, `((->) r)`

, which is `Reader r`

without the newtype wrapper), we have `m >>= f = flip f <*> m`

. That means if take the second do-block I wrote just above (or the analogous one in chepner's answer, etc) *and* assume the monad being used is `Reader`

, we can translate it into applicative style.

Still, with `Reader`

ultimately being such a simple thing, why should we even bother with any of the above in this specific case? Here go a few suggestions.

To begin with, Haskellers are often wary of the bare function functor, `((->) r)`

, and quite understandably so: it can easily lead to unnecessarily cryptic code when compared to "non-fancy expression[s]" in which functions are applied directly. Still, in a few select cases it can be handy to use. For a tiny example, consider these two functions from `Data.Char`

:

```
isUpper :: Char -> Bool
isDigit :: Char -> Bool
```

Now let's say we want to write a function that checks if a character is either an upper case letter or an ASCII digit. The straightforward thing to do is something along the lines of:

```
\c -> isUpper c && isDigit c
```

Using the applicative style, though, we can write it immediately in terms of the two functions -- or, I'm inclined to say, the two *properties* -- without having to note where the eventual argument goes:

```
(&&) <$> isUpper <*> isDigit
```

With an example as tiny as this one, whether to write it in this way is not a big deal, and largely up to taste -- I quite like it; others can't stand it. The point, though, is that sometimes we aren't particularly concerned about a certain value being a function, because we happen to be thinking of it as something else -- in this case, as a property -- and the fact it is ultimately a function can appear to us as a mere implementation detail.

A quite compelling example of this perspective shift involves application-wide configuration parameters: if every single function across some layer of your program takes some `Config`

value as an argument, chances are you will find it more comfortable treating its availability as a background assumption, rather than passing it around explicitly everywhere. It turns out that is the main use case for the reader monad.

In any case, your suspicions about the usefulness of `Reader`

are somewhat vindicated in at least one manner. It turns out that `Reader`

itself, the functions-but-wrapped-in-a-fancy-newtype functor, isn't actually used all that often in the wild. What *is* extremely common are monadic stacks that incorporate the functionality of `Reader`

, typically through the means of `ReaderT`

and/or the `MonadReader`

class. Discussing monad transformers at length would be a digression too far for the space of this answer, so I will just note that you can work with, for example, `ReaderT r IO`

much like you would with `Reader r`

, except that you can also slip in `IO`

computations along the way. It is not unusual to see some variant of `ReaderT`

over `IO`

as the core type of the outer layer of a Haskell application.

On a final note, you might find it interesting to see what `join`

from `Control.Monad`

does for the function functor, and then work out why that makes sense. (A solution can be found in this Q&A.)

notequivalent to`f (fa x) (fb x) (fc x) (fd x)`

. The`do`

notation is syntactical sugar, it means that you wrote`fa >>= \a -> fb >>= \b -> fc >>= \c -> fd >>= \d -> return (f a b c d)`

. Note that the`>>=`

depending on the monad does something different. – Willem Van Onsem Apr 22 at 16:14`fa >>= \a -> fb >>= \b -> fc >>= \c -> fd >>= \d -> return (f a b c d)`

actually is equivalent to`f (fa x) (fb x) (fc x) (fd x)`

– gaazkam Apr 22 at 16:15`Reader a`

monad and the`(->) a`

monad are isomorphic. The difference between them is only a wrapping constructor. You can choose either according to "taste", so to speak. I guess`Reader a`

is more used since it has a name, and the wrapping helps understanding what is thought as monadic and what is a regular function. – chi Apr 22 at 16:18`Monad`

is more powerful than`Applicative`

(as explained in chepner's answer), the`Reader`

/function functor is a very special case in which the`Monad`

and`Applicative`

instances happen to be equivalent -- see the second part of this answer of mine. (Cc. @RobinZigmond ) – duplode Apr 22 at 16:39