简体   繁体   中英

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?

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.

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 . Ie, 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 variant in its first argument. 变形来描述这一点。 But if it consisted of just a variable for the value and one for the environment, then it would be variant in both arguments (ie Int -> Integer would transform Reader Int A to Reader Integer A , not the other way around). 在两个参数变异(即Int -> Integer将改变Reader Int AReader Integer A ,而不是其他方式)。 Whereas a function type is contravariant in its left side.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM