haskell - 阅读器单子 - 阅读器与询问功能差异?
问题描述
reader monad有一个asks函数,它完全定义为reader函数,为什么它作为一个单独的函数存在,其定义与reader相同?为什么不总是使用阅读器?
class Monad m => MonadReader r m | m -> r where
-- | Retrieves the monad environment.
ask :: m r
ask = reader id
-- | Executes a computation in a modified environment.
local :: (r -> r) -- ^ The function to modify the environment.
-> m a -- ^ @Reader@ to run in the modified environment.
-> m a
-- | Retrieves a function of the current environment.
reader :: (r -> a) -- ^ The selector function to apply to the environment.
-> m a
reader f = do
r <- ask
return (f r)
-- | Retrieves a function of the current environment.
asks :: MonadReader r m
=> (r -> a) -- ^ The selector function to apply to the environment.
-> m a
asks = reader
解决方案
我找到了将这种冗余引入到transformers包和mtl包的补丁。补丁/提交描述......不是超级有启发性。但是,在这两种情况下,都asks
早于reader
,并且在这两种情况下,相同的更改都引入了state
和writer
原语。
所以,一些猜测:
- 据观察,将转换器/monad 类作为库中表示的概念的核心语义事物很方便。
- 为了可预测性,新的原语以提供该原语的转换器命名,仅此而已(
StateT
->state
;WriterT
->writer
;ReaderT
->reader
)。这种并行性使用户更容易记住他们想要的东西叫什么。 - 由于
asks
已经存在,它被保留了一些向后兼容性。
如果我们想要一个明确的答案,我们可能不得不询问这些变化的明显发起者 Ed Kmett 或 Twan van Laarhoven。
推荐阅读
- java - What's the C# equivalent of Java CharSequence type?
- google-maps - 我需要谷歌地图 API 吗?
- c - 使用 c 读取包括空格在内的整行
- c# - 无法在 .aspx 文件中设置断点(后面没有代码)
- php - how to use php to read xml file
- javascript - 在验证期间从自定义关键字代码访问“其他错误”?
- excel - 宏运行时突然变慢
- node.js - 如何以低优先级启动 puppeteer 进程?
- sql-server - 建议使用审计表而不是事务?
- c - gcc-8 Wstringop-截断