I am trying to figure out that how to use mapReader
from Control.Monad.Reader
.
For example I have this reader monad
myReaderMonad :: Reader String Int
myReaderMonad = do
string <- ask
return (length string)
I can run it like this
>>> runReader myReaderMonad "Saurabh"
>>> 7
Now I am trying to check the value returned by runReader is even or not.
Without using mapReader
I can do like this
>>> even $ runReader myReaderMonad "Saurabh"
>>> False
But I want to do this by using mapReader
https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Reader.html#v:mapReader
I tried the following but it is not working.
>>> 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"
Please help me here.
mapReader
doesn't suddenly turn your Reader
-computation into a plain function, it just turns it into another Reader
-computation.
The expression mapReader even myReaderMonad
doesn't return a function to which you could feed "Saurabh" as an argument. Instead, it gives you a Reader String Bool
.
Now that you have this new Reader String Bool
value, you can give it a string using runReader
and obtain a result:
> myEvenReader = mapReader even myReaderMonad
...
> runReader myEvenReader "Saurabh"
False
Or you can use it in some other way, for example put it through another mapReader
:
> myOddReader = mapReader not myEvenReader
...
> runReader myOddReader "Saurabh"
True