4

リーダー関数とまったく同じように定義されたリーダーモナドのasks関数がありますが、なぜそれがリーダーと同じ定義を持つ別の関数として存在するのですか? なぜ常にリーダーを使用しないのですか?

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
4

1 に答える 1

3

この冗長性をトランスフォーマーパッケージとmtlパッケージに導入したパッチを見つけました。パッチ/コミットの説明は...あまり啓発的ではありません。ただし、どちらの場合もaskspredatesreaderであり、どちらの場合も、同じ変更によってstatewriterプリミティブが導入されました。

したがって、いくつかの推測:

  1. トランスフォーマー/モナド クラスが行うコア セマンティックを、ライブラリで表現される概念として持つと便利であることがわかりました。
  2. 予測しやすいように、その新しいプリミティブは、そのプリミティブを提供したトランスフォーマーにちなんで名付けられました ( StateT-> state; WriterT-> writer; ReaderT-> reader)。この並列処理により、ユーザーは、必要なものが何と呼ばれているかを覚えやすくなります。
  3. すでに存在していたのでasks、下位互換性を維持するために保持されていました。

決定的な答えが必要な場合は、Ed Kmett または Twan van Laarhoven に尋ねる必要があるかもしれません。

于 2020-12-30T21:20:05.847 に答える