首页 > 解决方案 > 如何将 Control.Monad.Reader 中的 mapReader 用于 reader monad?

问题描述

我试图弄清楚如何使用mapReaderfrom Control.Monad.Reader

例如我有这个读者单子

myReaderMonad :: Reader String Int
myReaderMonad = do
  string <- ask
  return (length string)

我可以这样运行

>>> runReader myReaderMonad  "Saurabh"
>>> 7

现在我正在尝试检查 runReader 返回的值是否偶数。不使用mapReader我可以这样做

>>> even $ runReader myReaderMonad  "Saurabh"
>>> False

但我想通过使用mapReader https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Reader.html#v:mapReader来做到这一点

我尝试了以下但它不工作。

>>> mapReader even  myReaderMonad  "Saurabh"
>>> • Couldn't match expected type ‘[Char] -> t’
                  with actual type ‘ReaderT
                                      String Data.Functor.Identity.Identity Bool’
    • The function ‘mapReader’ is applied to three arguments,
      but its type ‘(Int -> Bool)
                    -> Reader String Int
                    -> ReaderT String Data.Functor.Identity.Identity Bool’
      has only two
      In the expression: mapReader even myReaderMonad "Saurabh"
      In an equation for ‘it’:
          it = mapReader even myReaderMonad "Saurabh"

请在这里帮助我。

标签: haskellmonadsreader-monad

解决方案


mapReader不会突然把你的Reader-computation 变成一个普通的函数,它只是把它变成另一个Reader-computation。

该表达式mapReader even myReaderMonad不返回您可以将“Saurabh”作为参数输入的函数。相反,它会给你一个Reader String Bool.

现在您有了这个新Reader String Bool值,您可以使用它给它一个字符串runReader并获得结果:

> myEvenReader = mapReader even myReaderMonad
...
> runReader myEvenReader "Saurabh"
False

或者您可以以其他方式使用它,例如通过另一种方式使用它mapReader

> myOddReader = mapReader not myEvenReader
...
> runReader myOddReader "Saurabh"
True

推荐阅读