是否可以将 M ⊗ M
理解为笛卡尔积,因此态射的定义域被定义为 M x M
?
完全正确。更具体地说,我们从 base 的 Monoid
类中选择 Hask(所有 Haskell 类型作为对象,所有 Haskell 函数作为态射的范畴)作为 C,(,)
(对类型构造器)作为 ⊗,()
(单位类型)作为 I 来得到这些由 Monoid
类表达的幺半群。然后,μ 和 η 的签名,翻译成 Haskell,变成了:
μ :: (M, M) -> M
η :: () -> M
通过将μ进行柯里化,并利用
() -> M
函数与
M
值一一对应的方式(它们都看起来像
\() -> m
,其中
m
是某个值),我们得到了熟悉的
Monoid
方法:
mappend :: M -> M -> M
mempty :: M
请注意,范畴论的定义远比 Monoid
更为普遍。例如,我们可以在保持使用 Hask 的同时,将 (,)
和 ()
替换为它们的对偶,Either
和 Void
,得到:
μ :: Either A A -> A
η :: Void -> A
每个 Haskell 类型都以这种特定的方式成为幺半群(μ 是 either id id
,而 η 是 absurd
)。
另一个例子是取 C 为 Haskell Functor
的范畴(它们之间的自然变换 - 我将其写为 type f ~> g = forall a. f a -> g a
- 作为态射),Compose
作为 ⊗,Identity
作为 I:
-- Note the arrows here are ~>, and not ->
μ :: Compose M M ~> M
η :: Identity ~> M
这两个通常被写成:
-- "Inlining" the definitions of Compose, Identity, and ~>
join :: M (M a) -> M a
return :: a -> M a
换句话说,一个 Monad 是范畴 Functor 中的幺半群(它是"一个 monad 是自函子范畴中幺半群"这个概念在 Hask 上的特殊版本)。需要提到的是,和前面的例子一样,这并不是从该范畴获得幺半群的唯一方法(请参考
此答案结尾的段落获取指针——实际上,它的其余部分可能也值得一读,因为它讨论了幺范畴的概念)。
I -> M
是从对象I
的一个态射。你为什么说I
不是一个对象?是的,M ⊗ M
是一种域。这些符号是由你引用的“一个融合范畴(C,⊗,I)”定义中引入的。 - Daniel Wagner