什么是 monad 范畴的函子?

What's a functor on the category of monads?

Note, this question is not about "monoids in the category of endofunctors". Nor is it directly about Functors (a Monad is always a Functor, but this question is concerned mainly about monad transformers)


Haskell 的 SelectT monad 转换器上的 docs 指出

SelectT is not a functor on the category of monads, and many operations cannot be lifted through it.

  1. 单子类别是什么?该类别中的箭头是什么?
  2. 为什么有些 monad transformers 函子属于 monad 类别(MaybeTRWST 等),而有些则不是(ContTSelectT)?
  3. 从编程的角度来看,作为 monad 范畴的函子有什么好处?作为图书馆的消费者,我为什么要关心?
  1. What's the category of monads? What are the arrows in that category?

对象是 monad 的类别,即 Type -> Type 类型 T 具有 Monad 个实例,箭头 A -> B它们的底层函子之间的自然变换,通常在Haskell中由forall x. A x -> B x类型的函数表示(尽管严格来说参数化是比自然性更强的条件)。

mmorph 包中有一个实现。

此类别中的初始对象是 Identity,因为对于任何 monad T 都有一个自然变换 forall x. Identity x -> T x。双重地,我认为最终对象是 Const ().

  1. Why are some monad transformers functors on the category of monads (MaybeT, RWST, etc), but some not (ContT, SelectT)?

此类别中的函子需要提升 fmap:

fmap'
  :: forall m n. (Monad m, Monad n)
  => (forall x. m x -> n x) -> forall x. T m x -> T n x

并且您不能对 ContTSelectT 通常实施此操作。我不确定为什么,但这似乎取决于方差:我们正在尝试实现 covariant 函子,但是 ContTSelectTinvariant 在它们的底层 monad 中,例如,mContT r m a 中的 (a -> m r) -> m r 中既有积极的也有消极的出现。

  1. What good does it do, from a programming perspective, to be a functor on the category of monads? Why should I care as a consumer of the library?

如果你有一个通用的方法来在 monad n 中“运行” monad m,你不一定要把它提升到 ContTSelectT;你遇到了像这样更受限制的映射操作:

mapSelectT :: (m a -> m a) -> SelectT r m a -> SelectT r m a
mapContT   :: (m r -> m r) -> ContT   r m a -> ContT   r m a

底层 monad 和结果类型是固定的。因此,您不能总是在使用这些转换器的堆栈中自由提升操作。