Control.Monad.Reader.withReader实际上是Data.Functor.Contravariant.contramap吗?
Is Control.Monad.Reader.withReader actually Data.Functor.Contravariant.contramap?
我正在阅读这本书 Haskell in depth,我注意到以下代码示例:
withReader :: (r' -> r) -> Reader r a -> Reader r' a
这看起来像 contramap
。 Control.Monad.Reader
和Data.Functor.Contravariant
有什么关系?
Reader
的类型参数顺序不正确,因此 contramap
。 Contravariant
函子在其最后一个类型参数中始终需要是逆变的,但 Reader
在其第一个类型参数中是逆变的。但是你可以这样做:
newtype FlippedReader a r = FlippedReader (Reader r a)
instance Contravariant (FlippedReader a) where
contramap f (FlippedReader x) = FlippedReader (withReader f x)
Reader
也几乎是一个 Profunctor
,有 lmap = withReader
和 rmap = fmap
,但这并不完全有效,因为 Reader r a
实际上是一个类型ReaderT r Identity a
的同义词(尽管您可以使用另一个 newtype
包装器使其像我上面那样工作)。 (->)
实际上是具有等效行为的 Profunctor
,并且它与 Reader
.
同构
我正在阅读这本书 Haskell in depth,我注意到以下代码示例:
withReader :: (r' -> r) -> Reader r a -> Reader r' a
这看起来像 contramap
。 Control.Monad.Reader
和Data.Functor.Contravariant
有什么关系?
Reader
的类型参数顺序不正确,因此 contramap
。 Contravariant
函子在其最后一个类型参数中始终需要是逆变的,但 Reader
在其第一个类型参数中是逆变的。但是你可以这样做:
newtype FlippedReader a r = FlippedReader (Reader r a)
instance Contravariant (FlippedReader a) where
contramap f (FlippedReader x) = FlippedReader (withReader f x)
Reader
也几乎是一个 Profunctor
,有 lmap = withReader
和 rmap = fmap
,但这并不完全有效,因为 Reader r a
实际上是一个类型ReaderT r Identity a
的同义词(尽管您可以使用另一个 newtype
包装器使其像我上面那样工作)。 (->)
实际上是具有等效行为的 Profunctor
,并且它与 Reader
.