有人可以简单地解释两者之间的区别吗?我并没有完全理解monad是endofunctor而不仅仅是functor的部分 .
仿函数可以从一个类别转到另一个类别,endofunctor是一个仿函数,其起点和目标类别相同 .
与内同态与态射相同 .
现在,为什么monad必须是endofunctors?
有一个着名的名言"Monads are just monoids in the category of endofunctors" . 幸运的是,其他人已经解释得相当好in this answer .
monad必须是一个endofunctor的关键点是 join ,因为它在Haskell中被调用,或 µ ,因为它通常在类别理论中被称为monad的定义¹的一部分 . 现在
join
µ
Prelude Control.Monad> :t join join :: Monad m => m (m a) -> m a
因此将函数 m 应用于对象(在Hask中,Haskell类型的类别作为对象和函数作为态射,类型)的结果必须是可以再次应用的对象 m . 这意味着它必须属于函子 m 的域的类别 .
m
如果一个仿函数的域和codomain是相同的[严格来说,如果它的codomain是其域的子类别],换句话说,如果它是一个endofunctor,那么它只能由它自己组成 . 由于与自身的可组合性是monad定义的一部分,monad是更好的endofunctors .
¹一个定义,可以使用 (>>=) 或 bind 定义monad,并将 join 作为派生属性 .
(>>=)
bind
1 回答
仿函数可以从一个类别转到另一个类别,endofunctor是一个仿函数,其起点和目标类别相同 .
与内同态与态射相同 .
现在,为什么monad必须是endofunctors?
有一个着名的名言"Monads are just monoids in the category of endofunctors" . 幸运的是,其他人已经解释得相当好in this answer .
monad必须是一个endofunctor的关键点是
join
,因为它在Haskell中被调用,或µ
,因为它通常在类别理论中被称为monad的定义¹的一部分 . 现在因此将函数
m
应用于对象(在Hask中,Haskell类型的类别作为对象和函数作为态射,类型)的结果必须是可以再次应用的对象m
. 这意味着它必须属于函子m
的域的类别 .如果一个仿函数的域和codomain是相同的[严格来说,如果它的codomain是其域的子类别],换句话说,如果它是一个endofunctor,那么它只能由它自己组成 . 由于与自身的可组合性是monad定义的一部分,monad是更好的endofunctors .
¹一个定义,可以使用
(>>=)
或bind
定义monad,并将join
作为派生属性 .