首页 > 解决方案 > 阅读器单子 - 阅读器与询问功能差异?

问题描述

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

标签: haskellmonadsreader-monad

解决方案


我找到了将这种冗余引入到transformers包和mtl包的补丁。补丁/提交描述......不是超级有启发性。但是,在这两种情况下,都asks早于reader,并且在这两种情况下,相同的更改都引入了statewriter原语。

所以,一些猜测:

  1. 据观察,将转换器/monad 类作为库中表示的概念的核心语义事物很方便。
  2. 为了可预测性,新的原语以提供该原语的转换器命名,仅此而已(StateT-> state; WriterT-> writer; ReaderT-> reader)。这种并行性使用户更容易记住他们想要的东西叫什么。
  3. 由于asks已经存在,它被保留了一些向后兼容性。

如果我们想要一个明确的答案,我们可能不得不询问这些变化的明显发起者 Ed Kmett 或 Twan van Laarhoven。


推荐阅读