I'm working trough the book Haskell in depth and I noticed following code example:
withReader :: (r' -> r) -> Reader r a -> Reader r' a
This looks like contramap
. What the relationship between Control.Monad.Reader
and Data.Functor.Contravariant
?
CodePudding user response:
Reader
's type parameters aren't in the right order for that to be contramap
for it. A Contravariant
functor always needs to be contravariant in its last type parameter, but Reader
is contravariant in its first type parameter. But you can do this:
newtype FlippedReader a r = FlippedReader (Reader r a)
instance Contravariant (FlippedReader a) where
contramap f (FlippedReader x) = FlippedReader (withReader f x)
Reader
is also almost a Profunctor
, with lmap = withReader
and rmap = fmap
, but that doesn't quite work since Reader r a
is really a type synonym for ReaderT r Identity a
(although you could use another newtype
wrapper to make it work like I did above). And (->)
actually is a Profunctor
with equivalent behavior, and it's isomorphic to Reader
.