Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Control.Monad.Reader.withReader actually Data.Functor.Contravariant.contramap?

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?

like image 274
senjin.hajrulahovic Avatar asked Nov 02 '21 22:11

senjin.hajrulahovic


1 Answers

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.

like image 138
Joseph Sible-Reinstate Monica Avatar answered Oct 08 '22 08:10

Joseph Sible-Reinstate Monica