Как использовать mapReader из Control.Monad.Reader для чтения монады? - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь выяснить, как использовать mapReader из 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"

Пожалуйста, помогите мне здесь.

1 Ответ

3 голосов
/ 27 апреля 2020

mapReader не внезапно превращает ваше Reader -вычисление в простую функцию, оно просто превращает его в другое Reader -вычисление.

Выражение 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
...