微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

什么是单子类的函子?

如何解决什么是单子类的函子?

请注意,这个问题与“ endofunctors类别中的monoids”无关。也不是直接与Functor有关(Monad始终是Functor,但是这个问题主要涉及monad变换器)


Haskell的SelectT monad变压器上的docs指出

SelectT不是单子类的函子,并且无法通过它进行许多操作。

  1. 单子的类别是什么?该类别中的箭头是什么?
  2. 为什么有些monad变换器的仿函数(例如MaybeTRWST等,而有些不是ContTSelectT)呢?
  3. 从编程的角度来看,成为单子类别的函子有什么用?为什么我应该作为图书馆的消费者呢?

解决方法

  1. 单子的类别是什么?该类别中的箭头是什么?

对象是单子对象的类别,即类型为T的{​​{1}}类型为Type -> Type的类型Monad,箭头A -> B自然变换在其底层函子之间,通常用forall x. A x -> B x类型的函数在Haskell中表示(尽管严格地说,参数性比自然性更强)。

mmorph软件包中有此实现。

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

  1. 为什么有些monad变换器的仿函数(例如MaybeTRWST等,而有些不是ContTSelectT)呢?

此类别的函子需要解除fmap

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

并且您通常无法在ContTSelectT上实现此功能。我不确定为什么会这样,但是它似乎取决于方差:我们正在尝试实现协变函子,但是ContTSelectT不变的在其基本单子中,例如m(a -> m r) -> m r内的ContT r m a中正反两面地出现。

  1. 从编程的角度来看,成为单子类别的函子有什么用?为什么我应该作为图书馆的消费者呢?

如果您有一般的方式可以在单子m中“运行”单子n,则不必将其提升为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和结果类型固定的位置。因此,您无法始终在使用这些转换器的堆栈中自由地提升动作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。