cibercitizen1
cibercitizen1

Reputation: 21496

Why does the Reader monad store a function?

According to All about monads

Monad values (of the Reader monad) are functions from the environment to a value. The bound function is applied to the bound value, and both have access to the shared environment.

But, why is it necessary to use a function (and not, for instance, two variables, one for the environment and one for the value) in this monad?

Upvotes: 3

Views: 268

Answers (2)

leftaroundabout
leftaroundabout

Reputation: 120711

A somewhat more mathematical argument:

Consider what happens when you modify the environment. For instance, say you have an environment with an Int in in, but your Reader requires an Integer. I.e., you have

yourReader :: Reader Integer A

Well, clearly you can convert the Int in the environment, just use

fromIntegral :: Int -> Integer

But what this means for your reader monad is that you convert to Reader Int A, because only that type works in your original environment.

yourReader' :: Reader Int A
yourReader' = withReader fromIntegral yourReader

Mathematicians describe this by saying Reader is contravariant in its first argument. But if it consisted of just a variable for the value and one for the environment, then it would be covariant in both arguments (i.e. Int -> Integer would transform Reader Int A to Reader Integer A, not the other way around). Whereas a function type is contravariant in its left side.

Upvotes: 4

chi
chi

Reputation: 116139

The point of the reader monad is to model a value which depends on some environment. Or, if you prefer, a computation with an "implicit" input. This is different from a value which is stored along its environment.

Consider this:

newtype Reader s a = Reader (s -> a)

ask :: Reader a a
ask = Reader (\s -> s)

here the value and the environment are the same. The above simply "gets" the value from the environment and returns it.

By contrast,

newtype Reader s a = Reader (s, a)

ask :: Reader a a
ask = Reader (s, s)
   where s = ???

here we need to produce both the environment and the value. But we have no actual way to do that! The environment moved from being an input, in the first example, to being an output -- and this makes realizing ask impossible.

Upvotes: 10

Related Questions