haskellmonadsreader-monad

Reader monad - reader vs asks function difference?


There is a asks function for reader monad, which defined exactly as reader function, why it exists as a separate function with a definition the same as a reader? why not always use 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

Solution

  • I found the patches that introduced this redundancy to the transformers package and the mtl package. The patch/commit descriptions are... not super enlightening. However, in both cases, asks predates reader, and in both cases, the same change introduced the state and writer primitives.

    So, some speculation:

    1. It was observed that it's handy to have the core semantic thing that the transformer/monad class does as a concept represented in the library.
    2. For predictability, that new primitives were named after the transformer that supplied that primitive and nothing else (StateT -> state; WriterT -> writer; ReaderT -> reader). This parallelism makes it easier for users to remember what the thing they want is called.
    3. Since asks already existed, it was kept around for a modicum of backwards-compatibility.

    If we wanted a definitive answer, we might have to ask Ed Kmett or Twan van Laarhoven, the apparent originators of the changes.