理解Reader monad

kaq*_*qao 11 monads haskell state-monad reader-monad purescript

我正在通过示例阅读Purescript并介绍了阅读Monad的部分.这个例子是这样的:

createUser :: Reader Permissions (Maybe User)
createUser = do
  permissions <- ask
  if hasPermission "admin" permissions
    then map Just newUser
    else pure Nothing
Run Code Online (Sandbox Code Playgroud)

对我来说令人困惑的部分是ask功能.签名是:

ask   :: forall r. Reader r r
Run Code Online (Sandbox Code Playgroud)

它看起来好像是凭空创造了一个阅读器

当我读到Statemonad时,它的get功能与概念相同.文字解释说:

状态被实现为State monad的数据构造函数隐藏的函数参数,因此没有明确的引用传递.

我猜这是关键,同样的事情发生在这里与读者,但我不明白它是如何工作的......

当上面的例子运行时runReader,提供的值如何突然出现ask?Haskell文档ask说:检索monad环境.但我的困惑是从哪里来的?我看到它的方式,一个值传递给runReader,存储在某个地方,并得到它 - 你打电话ask......但这没有任何意义.

虽然这个例子是Purescript,但我猜测任何有Haskell识字的人也能够回答,因此Haskell标签.

Mar*_*ann 11

我目前没有PureScript环境,因此我将尝试从Haskell的角度回答,并希望它有所帮助.

一个阅读器是真的只是一个围绕一个函数"包装",所以当你得到一个Reader r r,你真的只从吸引读者rr; 换句话说,一个功能r -> r.

可以凭空召唤功能,因为如果你是柏拉图主义者,我想他们总是存在......

当你使用do符号时,你'在'monad'中,所以上下文r是隐含的.换句话说,您调用一个返回r值的函数,当您使用<-箭头时,您只需调用该上下文.

  • Upvoted.从空气中召唤出这样一个"r - > r"函数的方法可能就是说出"id"这个咒语.(并且`id`是_only_这样的函数,这要归功于参数化.) (2认同)