什么是 "a function that you call" 什么是 "a function that call you"?

What is "a function that you call" and what is "a function that call you"?

我试图理解什么是 Haskell Reader monad,但我在书中的这一部分遇到了困难:

The “read-only” nature of the type argument r means that you can swap in a different type or value of r for functions that you call, but not for functions that call you. The best way to demonstrate this is with the withReaderT function which lets us start a new Reader context with a different argument being provided:

withReaderT 
  :: (r' -> r) 
  -- ^ The function to modify the environment. 
  -> ReaderT r m a 
  -- ^ Computation to run in the modified environment. 
  -> ReaderT r' m a 

那么,首先,您能否具体说明要考虑什么 "a function that you call" 以及要考虑什么 "a function that call you"?

我认为这只是英语语言的误解。当它说 "you" 时,它只是表示 "the code you are currently concerned with"。

如果你正在写一个函数myfunction:

myfunction x y = sqrt (x*x + y*y)
main = print $ myfunction 3 4

如果我们说你是myfunction,那么sqrt就是你调用的函数,main就是调用你的函数

这本书试图表达的观点是,您的代码可以在任何您想要的环境中调用函数,但这些函数不能改变代码的环境。反过来,调用您的代码的代码可以指定它希望您看到的任何环境,但您不能更改该代码的环境。

这是一个注释示例:

import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
import Control.Monad.Trans

showValue :: String -> ReaderT String IO ()
showValue str = do
    s <- ask
    lift . putStrLn $ str ++ ": " ++ s

-- This is me (i.e. my code). 
-- I show the environment twice, and it's guaranteed to be the same both times
myFunction :: ReaderT String IO ()
myFunction = do
    showValue "myFunction sees"
    withReaderT (const "Something Completely Different") functionThatICall
    showValue "myFunction still sees"

-- This is a function that I call.
-- I decide what value it sees, but it can't decide what I see.
functionThatICall :: ReaderT String IO ()
functionThatICall = showValue "functionThatICall sees"

-- This is a function that calls me. It decides what value I see,
-- but I can't change what it sees.
functionThatCallsMe :: ReaderT String IO ()
functionThatCallsMe = do
    showValue "functionThatCallsMe sees"
    myFunction
    showValue "functionThatCallsMe still sees"


main = runReaderT functionThatCallsMe "Hello World"