【发布时间】:2018-03-26 01:52:26
【问题描述】:
我正在阅读 PureScript by Example 并进入介绍 Reader monad 的部分。示例如下:
createUser :: Reader Permissions (Maybe User)
createUser = do
permissions <- ask
if hasPermission "admin" permissions
then map Just newUser
else pure Nothing
让我感到困惑的是ask 函数。签名是:
ask :: forall r. Reader r r
看起来好像它凭空创造了一个阅读器????
当我阅读State monad 时,它的get 函数具有相同的概念。以及文字说明:
state 被实现为一个隐藏在 State monad 的数据构造函数中的函数参数,因此没有明确的引用可以传递。
我猜这是关键,阅读器也发生了同样的事情,但我不明白它是如何工作的......
当上面的例子通过runReader运行时,提供的值是如何突然作为ask的结果出现的? ask 的 Haskell 文档说:检索 monad 环境。但我的困惑是 从哪里来的?在我看来,一个值被传递给runReader,被存储在某处,然后得到它——你调用ask...但这没有任何意义。
虽然这个例子是 PureScript,但我猜任何懂 Haskell 的人也能回答,因此有了 Haskell 标签。
【问题讨论】:
-
Reader a b是a -> b的包装。所以,ask :: forall a. Reader a a最终只是一个forall a. a -> a类型的值,并带有一个包装器。
标签: haskell monads purescript state-monad reader-monad