在范畴论中,一个单子可以由两个伴随函子构成。特别是,如果C和D是类别,并且 F : C --> D和G : D --> C是伴随函子,在某种意义上是双射
hom(FX,Y) = hom(X,GY)
对于C中的每个X和D中的Y,则组合G o F : C --> C是一个单子。
一对这样的伴随函子可以通过固定类型b
和取F
和G
来给出
data F b a = F (a,b)
data G b a = G (b -> a)
instance Functor (F b) where
fmap f (F (a,b)) = F (f a, b)
instance Functor (G b) where
fmap f (G g) = G (f . g)
并且通过currying给出hom集之间的双射(模构造函数):
iso1 :: (F b a -> c) -> a -> G b c
iso1 f = \a -> G $ \b -> f (F (a,b))
iso2 :: (a -> G b c) -> F b a -> c
iso2 g = \(F (a,b)) -> let (G g') = g a in g' b
在这种情况下,相应的单子是
data M b a = M { unM :: b -> (a,b) }
instance Monad (M b) where
return a = M (\b -> (a,b))
(M f) >>= g = M (\r -> let (a,r') = f r in unM (g r') a)
我不知道这个 monad 的名字应该是什么,除了它似乎是一个带有可覆盖信息的 reader monad(编辑: dbaupp 在评论中指出这是State
monad. )
所以State
单子可以被“分解”为一对伴随函子F
and G
,我们可以写
State = G . F
到现在为止还挺好。
我现在正试图弄清楚如何将其他常见的单子分解为成对的伴随函子 - 例如Maybe
, []
, Reader
, Writer
, Cont
- 但我无法弄清楚我们可以将它们“分解”成的伴随函子对是什么。
唯一简单的情况似乎是Identity
monad,它可以分解为任何一对仿函数,F
并且与(特别是,你可以只取and )相反。G
F
G
F = Identity
G = Identity
任何人都可以解释一下吗?