Skip to main content

第 28 章:富范畴(Enriched Categories)

原文:Bartosz Milewski, Category Theory for Programmers, Scala Edition, Chapter 28. 原书 PDF、.tex 源文件及相关图像采用 CC BY-SA 4.0;本译文按同一许可发布。

如果一个范畴的对象形成集合,它就是小范畴。但我们知道,有些东西比集合更大。著名的是,在标准集合论(Zermelo-Fraenkel 集合论,可选加上选择公理)中,无法形成所有集合的集合。因此,所有集合构成的范畴必须是大的。像 Grothendieck 宇宙这样的数学技巧,可以用来定义超越集合的收集。这些技巧让我们能够谈论大范畴。

如果任意两个对象之间的态射形成集合,一个范畴就是局部小的。如果它们不形成集合,我们就必须重新思考一些定义。特别是,如果我们甚至无法从一个集合中选出态射,组合态射是什么意思?解决办法是自举:用某个其他范畴 V 中的对象,替换作为 Set 中对象的 hom-set。区别在于,一般来说对象没有元素,因此我们不再允许谈论单个态射。我们必须用可以对整个 hom-object 执行的操作,来定义富范畴的所有性质。为了做到这一点,提供 hom-object 的范畴必须具有额外结构,它必须是一个幺半范畴。如果把这个幺半范畴称为 V,就可以谈论一个在 V 上富化的范畴 C

除了大小方面的原因之外,我们可能也有兴趣把 hom-set 推广为比单纯集合更有结构的东西。例如,传统范畴没有对象之间距离的概念。两个对象要么由态射连接,要么没有。所有连接到某个给定对象的对象都是它的邻居。与现实生活不同,在范畴中,朋友的朋友的朋友和密友离我一样近。在合适的富范畴中,我们可以定义对象之间的距离。

还有一个很实际的理由,值得积累一点富范畴经验:一个非常有用的在线范畴论知识来源 nLab1,大多以富范畴的语言写成。

28.1 为什么是幺半范畴?(Why Monoidal Category?)

构造富范畴时,必须记住:当把幺半范畴替换为 Set、把 hom-object 替换为 hom-set 时,应该能够恢复普通定义。实现这一点的最好方式,是从普通定义开始,不断把它们改写为 point-free 的形式,也就是不命名集合元素。

先看组合的定义。通常,它接收一对态射,一个来自 C(b, c),一个来自 C(a, b),并把它们映射为来自 C(a, c) 的态射。换句话说,它是一个映射:

C(b, c) x C(a, b) -> C(a, c)

这是集合之间的函数,其中一个集合是两个 hom-set 的笛卡尔积。这个公式很容易推广:把笛卡尔积替换成更一般的东西。范畴积可以工作,但还可以走得更远,使用完全一般的张量积。

接下来是恒等态射。不再从 hom-set 中挑选单个元素,而是可以用来自单元素集合 1 的函数定义它们:

j_a :: 1 -> C(a, a)

同样,我们可以把单元素集合替换为终对象,但还可以走得更远,把它替换为张量积的单位对象 i

如你所见,取自某个幺半范畴 V 的对象,是替代 hom-set 的好候选。

28.2 幺半范畴(Monoidal Category)

我们之前已经谈过幺半范畴,但这里值得重述定义。幺半范畴定义一个张量积,它是一个双函子:

tensor :: V x V -> V

我们希望张量积满足结合律,但只需要在自然同构意义下满足结合律。这个同构称为结合子。它的分量是:

alpha_abc :: (a tensor b) tensor c -> a tensor (b tensor c)

它必须在三个参数上都是自然的。

幺半范畴还必须定义一个特殊的单位对象 i,作为张量积的单位;同样,也是在自然同构意义下。两个同构分别称为左单位子和右单位子,其分量是:

lambda_a :: i tensor a -> a
rho_a :: a tensor i -> a

结合子和单位子必须满足相干条件。第一个是五边形恒等式,第二个是三角恒等式。它们保证所有不同的重新加括号方式,以及插入或移除单位对象的方式,都会给出相同的规范结果。

如果存在一个自然同构,其分量为:

gamma_ab :: a tensor b -> b tensor a

并且它的“平方为一”:

gamma_ba . gamma_ab = id_(a tensor b)

同时与幺半结构一致,那么这个幺半范畴称为对称的。

幺半范畴中一个有趣之处是,也许可以把内部 hom(函数对象)定义为张量积的右伴随。你可能还记得,函数对象或指数对象的标准定义,是通过范畴积的右伴随给出的。对任意对象 pair 都存在这种对象的范畴称为笛卡尔闭范畴。下面是在幺半范畴中定义内部 hom 的伴随:

V(a tensor b, c) ~ V(a, [b, c])

沿用 G. M. Kelly2 的记法,我用 [b, c] 表示内部 hom。这个伴随的余单位是一个自然变换,其分量称为求值态射:

epsilon_ab :: ([a, b] tensor a) -> b

注意,如果张量积不是对称的,可以用下面的伴随定义另一个内部 hom,记作 [[a, c]]

V(a tensor b, c) ~ V(b, [[a, c]])

两个内部 hom 都定义了的幺半范畴称为双闭的(biclosed)。一个非双闭范畴的例子,是 Set 中自函子的范畴,其中函子组合作为张量积。这就是我们用来定义单子的范畴。

28.3 富范畴(Enriched Category)

在幺半范畴 V 上富化的范畴 C,用 hom-object 替换 hom-set。对于 C 中的每一对对象 ab,都关联 V 中的一个对象 C(a, b)。我们对 hom-object 使用与 hom-set 相同的记法,只是要理解它们并不包含态射。另一方面,V 是普通的(非富化的)范畴,有 hom-set 和态射。所以我们并没有完全摆脱集合,只是把它们扫到了地毯下面。

由于不能谈论 C 中的单个态射,态射组合被替换为 V 中的一族态射:

compose :: C(b, c) tensor C(a, b) -> C(a, c)

富范畴中的组合

类似地,恒等态射被替换为 V 中的一族态射:

j_a :: i -> C(a, a)

其中 iV 中的张量单位。

富范畴中的恒等

组合的结合律用 V 中的结合子定义:

(C(c, d) tensor C(b, c)) tensor C(a, b)
-> C(b, d) tensor C(a, b)
-> C(a, d)

C(c, d) tensor (C(b, c) tensor C(a, b))
-> C(c, d) tensor C(a, c)
-> C(a, d)

单位律同样用单位子表达:

C(a, b) tensor i -> C(a, b) tensor C(a, a) -> C(a, b)
i tensor C(a, b) -> C(b, b) tensor C(a, b) -> C(a, b)

28.4 预序(Preorders)

预序定义为薄范畴,也就是每个 hom-set 要么为空,要么是单元素集合。我们把非空集合 C(a, b) 解释为 a 小于或等于 b 的证明。这样的范畴可以解释为在一个非常简单的幺半范畴上富化:该范畴只包含两个对象 01(有时称为 FalseTrue)。除了必需的恒等态射之外,这个范畴还有一个从 01 的单个态射,称为 0 -> 1。可以在其中建立一个简单的幺半结构,张量积模拟 01 的简单算术(也就是说,唯一非零乘积是 1 tensor 1)。这个范畴中的单位对象是 1。这是严格幺半范畴,也就是说,结合子和单位子都是恒等态射。

由于在预序中 hom-set 要么为空、要么为单元素集合,可以很容易地用这个小范畴中的 hom-object 替换它。富化后的预序 C 对任意对象 pair ab 都有一个 hom-object C(a, b)。如果 a 小于或等于 b,这个对象就是 1;否则就是 0

来看看组合。任意两个对象的张量积都是 0,除非二者都是 1,这种情况下张量积是 1。如果它是 0,那么组合态射有两个选择:可以是 id_0,也可以是 0 -> 1。但如果它是 1,唯一选择是 id_1。把它翻译回关系,就是说如果 a <= bb <= c,那么 a <= c,这正是需要的传递律。

恒等呢?它是从 1C(a, a) 的态射。从 1 出发只有一个态射,那就是恒等 id_1,所以 C(a, a) 必须是 1。这意味着 a <= a,也就是预序的自反律。因此,如果把预序实现为富范畴,传递性和自反性都会被自动强制。

28.5 度量空间(Metric Spaces)

一个有趣例子来自 William Lawvere3。他注意到,度量空间可以用富范畴定义。度量空间定义任意两个对象之间的距离。这个距离是一个非负实数。把无穷大也包含为可能值会很方便。如果距离是无穷大,就没有办法从起始对象到达目标对象。

距离必须满足一些显然性质。其一是对象到自身的距离必须为零。另一个是三角不等式:直接距离不大于带中间停靠点的距离之和。我们不要求距离对称,这一开始可能显得怪异,但正如 Lawvere 解释的,可以想象一个方向是上坡,另一个方向是下坡。无论如何,对称性可以稍后作为额外约束施加。

那么,怎样把度量空间转换成范畴语言?必须构造一个 hom-object 是距离的范畴。请注意,距离不是态射,而是 hom-object。hom-object 怎么会是一个数?只有当我们能构造一个幺半范畴 V,其中这些数是对象。非负实数(加上无穷大)形成全序,因此可以看成薄范畴。两个这样的数 xy 之间存在态射,当且仅当 x >= y(注意:这与传统预序定义中使用的方向相反)。幺半结构由加法给出,零作为单位对象。换句话说,两个数的张量积就是它们的和。

度量空间就是在这种幺半范畴上富化的范畴。从对象 ab 的 hom-object C(a, b) 是一个非负数(也可能是无穷大),我们称它为从 ab 的距离。来看看这样一个范畴中的恒等和组合会得到什么。

按我们的定义,从张量单位,也就是数字零,到 hom-object C(a, a) 的态射是关系:

0 >= C(a, a)

由于 C(a, a) 是非负数,这个条件告诉我们,从 aa 的距离总是零。通过!

现在讨论组合。从两个相邻 hom-object 的张量积开始:C(b, c) tensor C(a, b)。我们已经把张量积定义为两个距离之和。组合是 V 中从这个积到 C(a, c) 的态射。V 中的态射定义为大于等于关系。换句话说,从 ab 的距离与从 bc 的距离之和,大于等于从 ac 的距离。这正是标准三角不等式。通过!

通过把度量空间改写为富范畴,我们“免费”得到了三角不等式和自身距离为零。

28.6 富函子(Enriched Functors)

函子的定义涉及态射映射。在富化语境中,我们没有单个态射的概念,所以必须批量处理 hom-object。hom-object 是幺半范畴 V 中的对象,而我们可以使用它们之间的态射。因此,当两个范畴都在同一个幺半范畴 V 上富化时,定义它们之间的富函子是有意义的。随后就可以用 V 中的态射,在两个富范畴之间映射 hom-object。

两个范畴 CD 之间的富函子 F,除了把对象映射到对象之外,还会为 C 中的每一对对象指派 V 中的一个态射:

F_ab :: C(a, b) -> D(F a, F b)

函子是保持结构的映射。对于普通函子,这意味着保持组合和恒等。在富化语境中,保持组合意味着下面的图交换:

C(b, c) tensor C(a, b) -> C(a, c)
| |
F_bc tensor F_ab F_ac
v v
D(F b, F c) tensor D(F a, F b) -> D(F a, F c)

保持恒等被替换为保持 V 中那些“选择”恒等的态射:

i -> C(a, a) -> D(F a, F a)
i -----------> D(F a, F a)

28.7 自富化(Self Enrichment)

闭对称幺半范畴可以通过用内部 hom 替换 hom-set 来实现自富化(见上面的定义)。为了让它工作,必须为内部 hom 定义组合律。换句话说,必须实现一个具有下面签名的态射:

[b, c] tensor [a, b] -> [a, c]

这与其他编程任务没太大区别,只是在范畴论中通常使用 point-free 的实现。我们先指定它应该作为元素所在的集合。在这个例子中,它是 hom-set 的一个成员:

V([b, c] tensor [a, b], [a, c])

这个 hom-set 同构于:

V(([b, c] tensor [a, b]) tensor a, c)

这里我使用了定义内部 hom [a, c] 的伴随。如果能在这个新集合中构造一个态射,伴随就会指向原集合中的态射,然后就可以把它用作组合。

我们通过组合若干已有态射来构造这个态射。首先,可以使用结合子 alpha_[b,c] [a,b] a 来重新结合左侧表达式:

([b, c] tensor [a, b]) tensor a -> [b, c] tensor ([a, b] tensor a)

随后接上伴随的余单位 epsilon_ab

[b, c] tensor ([a, b] tensor a) -> [b, c] tensor b

再使用余单位 epsilon_bc 到达 c。于是构造出态射:

epsilon_bc . (id_[b,c] tensor epsilon_ab) . alpha_[b,c][a,b]a

它是下面 hom-set 的一个元素:

V(([b, c] tensor [a, b]) tensor a, c)

伴随会给出我们寻找的组合律。

类似地,恒等:

j_a :: i -> [a, a]

是下面 hom-set 的成员:

V(i, [a, a])

它通过伴随同构于:

V(i tensor a, a)

我们知道这个 hom-set 包含左恒等 lambda_a。可以把 j_a 定义为它在伴随下的像。

自富化的一个实际例子是 Set 范畴,它可作为编程语言中类型的原型。我们之前已经看到,相对于笛卡尔积,它是一个闭幺半范畴。在 Set 中,任意两个集合之间的 hom-set 本身也是一个集合,因此它是 Set 中的对象。我们知道它同构于指数集合,所以外部 hom 和内部 hom 等价。现在我们还知道,通过自富化,可以使用指数集合作为 hom-object,并用指数对象的笛卡尔积来表达组合。

28.8 与 2-范畴的关系(Relation to 2-Categories)

我在 Cat,也就是(小)范畴的范畴语境中谈过 2-范畴。范畴之间的态射是函子,但还有额外结构:函子之间的自然变换。在 2-范畴中,对象通常称为 0-cell;态射称为 1-cell;态射之间的态射称为 2-cell。在 Cat 中,0-cell 是范畴,1-cell 是函子,2-cell 是自然变换。

但请注意,两个范畴之间的函子也形成一个范畴。所以在 Cat 中,真正拥有的是 hom-category,而不是 hom-set。事实证明,正如 Set 可以看成在 Set 上富化的范畴,Cat 也可以看成在 Cat 上富化的范畴。更一般地说,正如每个范畴都可以看成在 Set 上富化,每个 2-范畴也可以看成在 Cat 上富化。

Footnotes

  1. nLab.

  2. G. M. Kelly, Basic Concepts of Enriched Category Theory.

  3. William Lawvere, Metric spaces, generalized logic, and closed categories.