集合论 vs 范畴论 = 汇编语言 vs C++?

范畴论是现代数学中重要的一门学科,已经对人们理解现代数学和物理问题产生了深远影响。简单来说,这是一门研究“关系”及其性质的学问,是数学的数学。但作为一项极为抽象的理论,繁杂的技术细节会令人望而却步。本文则从另一个角度,把范畴论作为谈论数学的语言,阐述其对思维方式的影响。文章作者深受范畴论影响,举出许多实例来辅以帮助理解范畴论的思想和哲学,希冀对我们理解范畴论,体会范畴的思考方式有所帮助。

撰文 | 叶凌远

前言

不知道大家有没有看过《降临》,这是一部科幻电影,根据特德·姜的小说《你一生的故事》改编而成。里面讲述了人类和外星人初次接触时的故事。这个科幻故事的立足点非常有趣,它基于一位语言学家和一位人类学家在 20 世纪中叶所提出的沙皮尔-沃尔夫假说(Sapir-Whorf hypothesis),有时也被称为语言相对论(linguistic relativity)。假说的主要内容是,一个人所掌握语言的内部结构会影响其思维方式和对世界的认知,于是使用不同语言的人其思维方式就不尽相同。在笔者的认识中,数学在某种意义上便是一门语言,尽管其是抽象的,但正是借助数学的抽象性,我们才能认识到客观世界背后的普遍规律。

今天这篇文章希望为读者介绍一下范畴论。范畴论的历史很短,还不到百年。它的创立脱胎于桑德斯·麦克莱恩(Saunders MacLane,1909-2005)和塞缪尔·艾伦伯格(Samuel Eilenberg,1913-1998)在 1945 年发表的论文General theory of natural equivalences。短短七八十年的时间,范畴论已经渗透进了现代数学的大多数领域,特别是代数几何和代数拓扑。

对大部分人而言,范畴论并不应该被理解成数学的一个分支;在某种意义上,范畴论应该被理解为谈论数学对象的语言。数学对象已是抽象的了,谈论抽象对象的语言本身只会更为抽象。我想这也许也是许多人不喜欢范畴论的原因。但从沙皮尔-沃尔夫假说的角度来看,学习范畴的语言,本质上是在学习范畴的思考方式;而这样的思考方式所带来的力量是没有掌握的人难以想象的——就像在《降临》中,掌握外星人的语言就意味着对时间的理解达到了其他人难以想象的程度。仅以笔者个人的经验来说,只有在学会了范畴的语言后才感到不同的数学对象和领域作为一个整体是可以被理解的。

尽管范畴论只有很短的历史,但它已经发展成为了一门非常丰富的学科,有许多的技术内容。范畴论所带来的洞见非常多,许多更加深刻的洞察也更为专业化。而在这篇文章中,我并不会介绍任何范畴论的技术细节,甚至都不会给出范畴精确的数学定义。我希望着重强调的是范畴论的思考方式,这才是对大多数读者而言最有用的部分。范畴论所带来的洞见非常多,但许多更为深刻的洞见也更为专业化。本文只在最基础的层面讲讲范畴论对我们思考问题的方式所带来的转变,希望这能够激起部分读者的兴趣,以致能够更加深入地学习范畴论的内容。这篇文章凝结了笔者很长时间思考的积累,希望能对读者有所启发。全文共 9000 字左右。

什么是范畴?这个问题放在不同的语境中会有不同的答案。早在古希腊时期,亚里士多德就写过著名的《范畴篇》(Categoriae),探究能被人所认知的对象的分类问题。在现代数学的语境下,范畴有其另外的含义和精确的数学定义,但对其最基本的直观是不变的:将一类相似对象聚合到一起便组成一个范畴。

我们从小学开始的数学教育似乎培养了这样的观念:我们总是更倾向于对某单个数学对象进行研究和学习。当我们拿到一个抽象的数学对象,无论它是某个拓扑空间,还是一个群或者向量空间,亦或是一个光滑流形等等,我们可能想到的第一个问题便是这个对象是由哪些元素构成的。换句话说,我们大多数时候研究一个数学对象的方式是从其自身的内部结构入手。粗略地说,这是集合论给我们提供的对数学对象的基本思考方式。

范畴论提供了另外的思路:我们可以从对象之间的关联来研究一个对象所具有的性质。一个范畴不是单单把一类对象放在一起就好了,这些对象之间还有许多不同的关系。我们可以把所有的群放在一起构成群的范畴,但群与群之间还通过群同态相关联;我们也可以把所有的拓扑空间放在一个构成拓扑的范畴,但拓扑空间之间还有连续函数相关联。因此,更准确地说,范畴是一类物体和它们之间的关联,或采用更数学的语言——态射——所构成的一个整体。我们可以把所有群构成的范畴记为Grp,把所有拓扑空间构成的范畴记为Top。类似的,我们把所有的集合所构成的范畴记为Set(从数理逻辑的角度,Set可以理解为你喜欢的公理集合论系统如 ZF, ZFC, ZFC+CH,甚至是 ZF+Atoms 等等的一个模型)。

从我们原本已有的知识可知,许多定义可以等价的用对象之间的态射来表述。一个子群可以等价地看作一个单的群同态,一个群的商群(或正规子群)可以等价地看作一个满的群同态;正如一个子集可以等价地看作一个单射,一个商集可以等价地用满射来表述。

可能相比子结构和商结构更难以直接观察到的是,我们遇到的大部分普适的数学构造都可以用对象之间的态射来表述。这里仅举一个例子。

集合的笛卡尔积被定义为如下的一个集合:

我们可以有类似的总结:范畴论是根据功能(或者说与其他对象的关系)来定义和描述一般的对象的。

此处插一句题外话。上面提到的证明和泛性质之间的关联其实反映了逻辑与范畴论之间更加深层次的对应。在某种特定的意义下(我必须要强调不是在所有意义下),逻辑和范畴是等价的。但这篇初步介绍范畴论思想的文章无法涵盖这更深层次的联系。

粗略地说,这就是奠定整个范畴论基础的 Yoneda 引理讲述的内容:在一个范畴中,满足同样泛性质的结构之间必定是同构的(这只是对 Yoneda 引理的粗略描述,感兴趣的读者可以自行查找更为精准的表述)!用数学家的语言来说,泛性质在同构的意义上定义了笛卡尔积。

为什么我们只希望在同构的意义上定义对象?或者更加广泛地,为什么采用泛性质、关注对象的功能和与其他事物之间的联系的思考方式对我们是更有用的?接下来仅仅列举一些对我而言十分重要的原因。

数学关心的是“结构”而不是具体的某个“对象”

以范畴论为基础发展出了一个数学哲学的流派,称为结构主义(structuralism)。在此我特别强调,这一部分所叙述的不应该看作严格的哲学论述,只是为大家提供一个直观而已,所以标题中的“结构”和“对象”均打上了引号。如果在数学哲学的语境下讨论结构主义的观点与内容,我们需要更为严谨的表述。

结构主义有关数学的一个基本论断是,真正有数学实质内容的是一些“结构”,而不是某个具体的“对象”。这样说起来非常抽象,让我们举一个例子来看看。或许我们最为熟悉的数学对象是自然数,在它上面我们能做基本的算术运算,例如加法、乘法等等。但如果你非常认真地看待集合论并认定它作为数学基础的话,那你可能会问:这些自然数(比如 1)所对应的集合是什么呢?这是一个可以合理问出的问题,因为在集合论的意义下一切数学对象均应该是一个集合。

历史上数学家们给出了不同的定义。公理集合论的奠基人的策梅洛(Ernst Zermelo,1871-1953)定义了如下的集合作为自然数:

或许更为严重的是,一旦我们把单个自然数看作是一个确定的集合,由此会问出一些非常不自然且我们完全不关心的问题,比如“空集是否是 5 的一个元素”?在集合论的语境下,这是一个我们可以合理问出的问题,但这个问题的答案和我们理解自然数是无关的。

关于上面这个问题,一个更为数学的回答则是:这两种自然数的定义都是合理的,具体采取哪一个取决于你的审美或你认为哪一个用起来更加方便。之所以这两种定义(还有其他无穷多种定义)都是合理的,是因为这两种定义下的自然数结构是同构的。换句话说,如果我们细心仔细的在这两种自然数下都用集合论的操作定义好加法、乘法等数学运算,选择哪一种进行运算必定不会对我们得到的结果产生任何影响。回到我们在这一节所强调的哲学上来,这说明我们关心的是自然数上这些加法、乘法等所具有的运算结构,而不是每个自然数自身的内部结构和构成。换句话说,任何与上面两种定义的自然数同构的结构都是好的,我们只在同构的意义上关心自然数。

由之前的叙述可见,范畴论提供了一个非常自然的关心数学结构的环境:在范畴论的思考方式下,我们总是在同构的意义上考虑数学问题。这和数学真正运作的方式更加接近,同样也非常有利于我们对问题的思考。我将在后一个部分更加深入地阐释后面这一点。

在这一节的最后,我想再次说一说这种思考方式和逻辑之间的关联。现代逻辑的思想本质在这一点上其实和范畴论非常类似;但在逻辑中,我们实现只关注“结构”而不是具体“对象”的方式是通过严格地区分语形(syntax)和语义(semantics)。

比如,我们同样可以考虑在逻辑中如何认识自然数的问题。在数理逻辑的语境下,我们对自然数的刻画是通过公理系统来实现的,比如皮亚诺算术公理系统 PA 或者其他 PA 的扩展,甚至是高阶的算术系统。如果考虑某个算术系统,这个系统是从语法上来对自然数的结构进行刻画,而不关心自然数的具体构成。例如,如果两个结构之间是同构的,且其中一个是 PA 的一个模型,则另一个也自动地是 PA 的一个模型。

以此来看,逻辑上对语形和语义所做的区分和范畴论的思想是十分同步的。这个联系同样有非常深刻的数学内涵,它标志着我们的语形和语义之间的某种对偶,但可惜的是,无法在这篇文章有限的篇幅内介绍与此相关的更多内容了。

范畴论是数学的高级语言

基于前面提到的“结构”与“对象”的区分,我们以一个更加直观的信息论的方式再来进一步说明为何范畴论的思想如此有价值。这一节我想要阐述的基本是如下的这个比喻:如果说集合论相当于数学的汇编语言,范畴论则相当于数学的高级语言。

这个比喻可能并不完全准确,因为对计算机来说汇编语言所能够实现的,严格大于任何一个高级语言能够实现的功能。但有许多数学家和哲学家却认为范畴论本身能够作为数学的基础而存在(笔者本人其实对此持怀疑态度),不过这个比喻有助于我们理解范畴论的思想。同时直观地来讲,这也是一个宣传范畴论有力的标语——我想毕竟只有异常少数的人才会喜欢汇编语言胜过 C++ 或 python。

从上面编程语言的比喻来看,对于任何一个日常的操作,汇编语言总是包含了很多我们不需要知道的冗余信息。假设我们想完成一个读取文档内容的操作。若通过汇编语言的方式来实现,我们可能需要说明 CPU 线程具体的运行方式,且可能还需要指定读取后的文档具体存放在内存的哪一部分空间等等。我们最终得到的可能是一个相对较长的程序结构。但对于我们的目标而言,这些一切的一切我们都毫不关心;一般在任何一门高级语言中,可能只要一两行代码就能够实现我们所需要的读取文档的功能,而剩余的操作则由编译器自动帮我们完成。

如果你对编程不熟悉,我再举一个日常生活中的例子。在现代,我们对身边许多物体的使用都是以功能为基础的。我们知道手机可以用来打电话聊微信上网听音乐,但我们从不会询问这些功能具体是怎么实现的。对日常生活来说,我们与这些东西的互动完全基于这些东西的功能;知晓这些功能是如何实现的不仅不会对我们的日常生活有任何的帮助,反而还会把事情复杂化,导致我们更难在纷繁复杂的细节信息当中找到对我们有用的部分。

更为重要的是,范畴论也并不在任何意义上阻碍我们探查更为细节的层面!反而,范畴论提供了非常好的工具让我们在不同的语境下关注不同的内容。在日常生活的交互中,我们可以只关心手机的日常功能,但没有任何理由阻止我们把手机拆开来看,关心各个手机模组是如何合作实现了某个具体功能的。在这个转换中我们只是换了一个范畴来考虑:从手机与人类交流关联的这个范畴转移到了单个手机间各个模组相互交换信息的范畴!但即使在这个更为细节的范畴中,我们仍然有不想考虑的细节对象。比如我们希望把 CPU、电池、WI-FI 等模组作为整体来考虑,而不是考虑其内部二极管或其他电器元件的排布等,但我们也可以再度换一个范畴考虑与此相关的问题。

如果用一句话来总结,范畴论的基本思想反映了我们对“复杂信息的组织方式”。在现实世界中,这是非常行之有效的思考问题的方式。对数学来说,可能我之前所举的例子都过于微不足道,以至于是否使用范畴论的语言对我们并没有实质性的影响。但在我们面对现代数学越来越庞杂的数学对象时,你一定会发现范畴论的思考方式能够极大地帮助你抓住问题的主干,让你的思考更有条理。

最后,我想说范畴论的思想不止停留在这个层面。如果只是对复杂信息进行分层,从原则上其实也并不一定需要采取范畴论的语言来完成这件事。但范畴论还包含了强大的工具帮助我们探究不同范畴或者说信息层次之间的关联(回忆范畴论的基本哲学总是让我们考虑对象之间的关联)。实现这一点我们进一步需要函子(functor)和自然变换(natural transformation)等数学概念。感兴趣的读者可以进一步查询文献进行了解。

Knowing How V.S. Knowing Why

举一个我身边遇到的例子。我做凝聚态实验的室友最近在学习拓扑。他在理解商空间的时候遇到了很大的障碍。在点集拓扑的语言下对商空间有一个利用开集写下的定义,但这个定义较为复杂,用其证明一些商空间的性质就像是在做脑筋急转弯。然而,商空间同样有一个采用泛性质来进行定义的方式。换句话说,通过说明我们希望商空间所具有的功能,我们便能够在同构的意义上确定商空间。更为重要的是,任何针对商空间基础的、有意义的问题都能通过商空间的泛性质来进行解答。事实证明,我的室友发现泛性质要比开集的定义直观很多,也更容易用其来证明有关商空间的结论。

为什么会出现这样的现象?我想这与我们常常感受到的 Knowing How 和 Knowing Why 的区别有关。从小学到高中再到大学,面对一道不会做的题,我们看到答案后往往会恍然大悟;从认识论的角度来看,针对这道题,在看到答案的时候,我们就有了 knowing how 的知识,即我们知道如何做这道题了。但同样普遍的是,下次遇到一个类似的题目我们仍然不会做。这表明我们缺乏 knowing why 的知识,即这道题的答案为什么要这样做?或者我们为什么要进行这样的一个构造?

Universality

最后,我想接着上面谈到的 knowing how 和 knowing why 的区别,谈谈范畴论对我们理解数学更进一步的帮助。大家回忆,我们在文章的最初举到了不同的范畴的例子。有集合构成的范畴Set,有群构成的范畴Grp,有拓扑空间构成的范畴Top,等等。但如果考虑笛卡尔积的泛性质描述,你会发现范畴论定义的另一个巨大的优势:我们并不依赖与某个具体的范畴给出了笛卡尔积的表述;相反,对任意一个范畴我们都可以根据泛性质的定义谈论这个范畴中的笛卡尔积!如果你进行验证,你会发现在群论中定义的两个群的笛卡尔积,在Grp这个范畴下满足我们上面表述的笛卡尔积的泛性质;同样的,两个拓扑空间的乘积拓扑在Top中也满足笛卡尔积的泛性质!

这进一步表现了泛性质定义的两个巨大的优势。先谈一谈同样与 knowing how 和 knowing why 相关的优势。如果我问,为什么我们的乘积拓扑空间所具有的乘积拓扑要如此定义?你可以思考一下你会怎么回答。初学者可能说这是非常自然的;毕竟在欧几里得空间中有着这样的直观。但随着我们定义的数学对象变得更加复杂,我们的直观很难继续产生作用。比如对于无穷多个拓扑空间乘积的乘积拓扑定义便很大程度上不是直观的。寻找这些 knowing why 的问题的答案同样要回到我们的泛性质。和商空间的定义一样,我们之所以要如此定义乘积拓扑和无限乘积的拓扑,是为了让它满足合适的泛性质。我相信对这一点的强调已经足够了。

但更为重要的优势是,范畴论在观念层面统一了不同数学分支中的定义与概念。在范畴论发展之前,我们只有一个模糊地印象认为乘积拓扑、群的笛卡尔积和集合的笛卡尔积是“类似”的,但范畴论使得我们进一步清晰地认识到它们之间具体的关联:这些构造都是同一个概念在不同语境下的具体体现方式。这也是笔者为什么对范畴论情有独钟的原因。现代科学发展的一个非常明显的趋势便是学科之间的划分;不同领域的知识似乎被划分地越来越精细,我们越来越难以对其有一个整体的认识与把握。但范畴论的出现部分地打通了数学在观念层面上的分野,它找到了数学不同分支之间相同的观念基础!这实在是太难能可贵了!

最后的话

本文还没有真正写下范畴的定义,就已经讲了如此之多范畴论的思想与哲学了,不知是否算是一个成功的尝试;且一不小心字数可能过于得多了,只希望能对读者有些许帮助。或许读者可以从行文中读得出来,笔者真的深受范畴论的影响,并真心地认同范畴的语言。本文大部分例子都看起来非常微不足道异常简单,且可以肯定的是不借助范畴的语言大部分人也能够掌握本文中提到的数学内容,但当之后面临更加复杂的数学对象,你会发觉范畴的思考方式成为了必要。即使你不会面对那么复杂的数学对象,范畴的语言也会让你对数学有着更加整体的把握和理解,这始终是一个好事。

本文原文发表于知乎,经作者重新整理后发表于《返朴》。