范畴论与 Haskell 程序设计(零):大纲

This process of hierarchical decomposition and recomposition is not imposed on us by computers. It reflects the limitations of the human mind.
— Bartosz Milewski, Category Theory for Programmers: The Preface

序

工程学的核心是管理复杂性。面对庞大、混沌、错综交织的现实需求,我们几乎只有一种武器:分解。我们将大问题分解为小问题,将复杂的模块分解为简单的单元,这是我们作为工程师的本能,也是我们唯一的本领。这并非计算机强加于我们的思维范式,它根植于人类心智的局限性。

对于如何分解,如何抽象,如何组合,也许每一位程序员都有自己的想法。世界上有这样一群人,我们混迹各种编程话题,难免会注意到他们的存在:

  • 出没在各种函数式编程社区,通篇充斥着抽象废话 (abstract nonsense);
  • 热衷于展示一些难懂的交换图,但看起来只是装模做样;
  • 喜欢嘲讽任何非纯的程序语言,尤其是取笑这些语言的锁机制;
  • 标榜自己的代码只在主逻辑传入参数,定义函数根本不需要形参;
  • 转身打开编辑器偷偷写一些 do ... return ... 这样看上去和其他语言别无二致的东西;
  • 被吃瓜群众问到以后,涨红脸说些“非纯……Monad 的事,能叫非纯吗……”这样难懂的话;
  • 被要求解释一下什么是 Monad,叽里咕噜半天,什么打开盒子装进盒子,一些具体的抽象废话;
  • 现实中,据说这些人真的参与大型软件项目,但谁也没在身边见过,打听来打听去,好像这些人只能混迹在银行和铁路这些老古董行业,什么?编译器?那也是老古董!
一些对 Haskell 程序员并不刻板的印象

我本人并非 Haskell 程序员,甚至也不是函数式编程的拥趸。在很长一段时间里,我对“他们”的态度是,保持好奇,同时敬而远之。我不相信范畴论可以指导任何现实中的软件设计问题,我认为设计模式——连同其他面向对象设计原则——已经足够解决我在实际编码工作中遇到的所有问题了。如果说在范围之外还有别的问题,那一定涉及到如何安排开发周期,如何组织团队协作,如何面对需求变更,诸如此类,而这是软件工程的领域,和编程语言无关。

起初,我认为他们——我是指 Haskell 程序员——并没有严肃对待软件设计问题。在我看来,他们更像一群沉迷于智力游戏的数学爱好者,而非愿意弄脏双手的工程师。当我们在现实的泥潭中与并发、状态管理和异常搏斗时,他们冷漠地打量着我们,偶尔推销一些不着边际的银弹,用以解决一些仅存在于他们想象中的问题。

后来我遇到了一些困难,超出了我的认识范围,我误打误撞在 Haskell 社区中找到了需要的东西,它如此简洁、紧凑、纯粹、浑然天成,任何人看到它都会认为“没错,编程本来就是这样!”。我并不准备将这个故事放在开头,我们会在后面的章节逐渐分享它。总之,在那之后,我突然明白,对于软件设计,他们和我们的身份一样,也是勤勉而热烈的工程师,我们都勇敢且真诚地面对软件内生的复杂性[1]。他们使用的语言和概念不是抽象废话,那是他们的哲学,他们的世界观,是一套切实可行,甚至可以说高效的工程范式,只是——只是与我们这一套不同,非常,非常不同。

然而,通往新世界的大门似乎并不情愿为外来者敞开。Haskell 社区常常给我一种极端排外的印象。他们的文字间充满各种隐晦、难以理解的暗号和密语。所谓入门材料,也大多晦涩难懂,往往在展示了 map 和 filter 的简单用法后,立即将读者抛入自函子范畴的风暴中,吝于提及沿途的风景和危险。这道——我认为是人为构筑的——鸿沟吓退了无数像我一样满怀好奇的冒险者,也让 Haskell 社区与我们距离越来越远,愈发陌生。

这份讲义是我们为后来者绘制的地图。我希望它能从我们熟悉的、经验驱动的工程世界出发,径直联接到与那个看似遥远的、由范畴论构建的形式化领域。我们绝不会回避那些艰深的概念,但我们会从直觉出发,用我们共通的工程师视角认识它们的轮廓,揭示它们在代码中的具体形态,探索它们如何解决现实的工程问题——我们终究还是乐于弄脏双手,因为我们认同自己是勤奋勇敢的工程师。

对读者的期待

严格讲,在大灾变[2]之后的今天,学习任何领域的内容都不再需要传统意义上的“预备知识”。只要读者擅长思考和提问,有一套内化的元学习框架,那么读者必定可以从一份基础材料出发,通过向 LLM 提问从而完整掌握材料涵盖的知识。

我们期待读者对一切充满好奇,至少此刻对范畴论和函数式编程充满好奇,这是整个旅途中持续驱动读者向更远方、更深处探索的力量源泉,也是我们唯一的“硬性要求”。那些真正走完全程,在终点开启宝箱的人,并不是因为他们多么强大、多么聪明——甚至不是因为他们比别人更自律——而是因为他们有不得不奋力向前的理由,他们好奇远方的地平线之下会是怎样的风景,他们好奇宝箱里藏着什么,他们好奇站在终点回望来时路的心情,直到最后,他们在终点远眺新的地平线,整理行囊,向仍旧陌生的远方继续进发。我们心照不宣,其实马里奥从来不在乎碧姬公主[3],星之卡比也根本无意营救瓦豆鲁迪,不过是顺手为之,这些远非支撑冒险的理由。一切都出于——也仅仅出于——我们最原始、最强烈的情感,那便是好奇心。

无人在意瓦豆鲁迪

不过,有些读者更习惯从书本中进入一个新领域,先建立一套连贯的概念地图,再按需查漏补缺,这是非常高效的学习习惯——即使在大灾变后也是一样。为此,我们推荐两本入门读物:

  1. 《计算机程序的构造与解释》:大名鼎鼎的 SICP,如果将函数式编程看作一门真正的外语[4],比如英语,那 SICP 就相当于《新概念英语》。你后来意识到它有这样那样的局限和缺憾,但当你回忆对这门外语最初的感觉,那些模糊的轮廓和形貌,无一例外都源于它。你不会后悔读过它,因为是它教会你如何用这门外语思考和表达。切换到技术性的视角:在前两章,书中将 map 应用在多种数据结构上,引导读者思考背后的共性,暗示了函子 (functor) 的存在;类似还有 accumulate 暗示了幺半群对象 (monoid object)——只是 SICP 并未明文点出这些概念。同时,第二章的许多概念为 Haskell 提供了雏形,例如2.2 层次性数据和闭包性质,这一节与代数数据类型 (ADT) 有着直接关联;还有2.5 带有通用性操作的系统,我们熟悉的类型类(type class)正是在这个想法启发下诞生的。在第三章,读者会直面现实的混沌,认识纯函数和非纯函数,并养成自己的品味——你愿意为了一方面的优势而容忍另一方面的代价吗?作为整本书最深刻的“巧合”,在3.5 流这一节中,SICP 事实上在流计算中完整构造了一个 Monad——我们的讲义将会解释为何会出现这种巧合。当然,SICP 还包含无数我们没有精力提及的概念,例如惰性求值、抽象屏障等等,它们同样重要,我们鼓励读者花点时间弄明白这些概念。最后——我是说真正的最后,在读者,还有我,完成这份讲义后,演出谢幕之时——我们可以回去看看2.1.3 数据意味着什么,在范畴论的“高观点”下,我们能回答这个问题吗?
  2. 《Haskell 趣学指南》:这本书可以帮助读者了解 Haskell 的基本语法,强化函数是一等公民的概念,通过 map 和 fold 巩固函数式编程的初步直觉,通过二叉树的例子接触持久化数据结构——这是纯函数式语言最地道 (idiomatic) 的数据结构。读者会接受充分的训练,学会识别 Haskell 对象的类型签名,然后越来越熟练,越来越快。我们特别推荐第十二章的走钢索,这是 Monad 最好的入门实例,如果读者在任何时候觉得自己迷失在 Monad 的森林里,都可以折回来再看一眼这个例子。况且,扮演一个走钢索的杂技演员本身也很有趣。

我们期待读者接受过基本的数学训练——别担心,请放松,继续读下去——这大致等同于说读者不患有公式恐惧症,并且赞同适当的形式化有助于更准确地、更紧凑地组织概念。人的认知资源[5]高度有限,更紧凑的表示 (representation) 使得我们可以更自如地思考和表达。

我们期待读者在旅途中保持审慎、保持质疑。作者不是首都派驻 12 区的导师斯诺,作者和读者一样,共同参与一场盛大的冒险——只是作者出发稍早。我们同样机敏、勇敢、雄心勃勃,我们一同翻越高山,遁入深谷,但务必小心,我们也许会在峭壁上一脚踩空,在阴影中摸黑摔倒,我们在任何一处都可能犯错!也许作者将一张错误的地图交到读者手中,包括定义、概念解释、实例、隐喻、引申,乃至思维方式——这一切都有可能出错!我们鼓励读者质疑讲义中任何含糊、模棱两可、甚至看上去明显有问题的地方,鼓励读者时刻保持警惕,在作者企图蒙混过关的时候,抓住他!

最后,我们期待与读者保持沟通,评论、邮件、微信、Github issue——我们欢迎任何途径!范畴论是关于联接的科学,我们以文本为媒介与读者建立联接,我们将会看到,正是联接,让孤立的对象成为范畴,让人类个体成为人类社会,让你和我,成为我们。

符号与样式

数学部分

首先约定一下数学概念的符号和样式:

  1. 范畴 (category) 使用英文草书体大写字母 \mathcal,例如一般的范畴 $\mathcal{C},\ \mathcal{D}$,还有 Hask 范畴 $\mathcal{H}$
  2. 对象 (object) 使用英文意大利体大写字母,即数学环境的默认字体,例如 $A,\ B,\ X$
  3. 态射 (morphism) 使用英文意大利体小写字母,例如 $f,\ g$;特别地,用 $1_{X}$ 表示对象 $X$ 的单位态射;态射复合记为 $g \circ f$;用 $\mathrm{Hom}_{\mathcal{C}}(A,\ B)$ 表示“范畴 $\mathcal{C}$ 上从对象 $A$ 到对象 $B$ 的所有态射组成的集合” ,上下文清楚时——几乎是所有时候——我们省略下标,直接记为 $\mathrm{Hom}(-,\ -)$
  4. 函子 (functor) 同样使用小写字母,但使用德文尖角体 \mathfrak,以便与态射区分,例如 $\mathfrak{f},\ \mathfrak{g}$;用 $\mathfrak{f}(A)$ 和 $\mathfrak{f}(h)$ 分别表示函子 $\mathfrak{f}$ 的对象映射和态射映射
  5. 自然变换 (natural transformation) 使用小写希腊字母,例如 $\alpha,\ \eta$;如要强调该变换在某对象 $X$ 上的分量 (component),用对象名作为下标,即 $\alpha_{X}$
  6. 在自函子范畴 (endofunctor category) 上,沿用德文尖角体表示自函子;特别地,恒等函子记为 $\mathfrak{id}$,函子 $\mathfrak{f}$ 到自身的恒等自然变换记为 $\mathrm{id}_{\mathfrak{f}}$;用 $\beta \circ \alpha$ 表示两自然变换的竖直复合,这与态射复合的记号保持一致;用 $\gamma * \eta$ 表示两自然变换的水平复合;此外,用 $\mathrm{Endo}(\mathcal{H})$ 表示 Hask 范畴的自函子范畴;在提及恒等函子对某对象 $X$ 的作用时,我们习惯直接用 $X$ 代替 $\mathfrak{id}(X)$
  7. 积 (product) 的泛性质 (general property) 用三元组 $\{A \times B,\ p_{1},\ p_{2}\}$ 表示;另一方面,余积 (coproduct) 的泛性质用三元组 $\{A+B,\ i_{1},\ i_{2}\}$ 表示;用 $h=\left<f,\ g\right>$ 表示积和余积的态射运算
  8. 用德文尖角体大写字母表示图示 (diagram),多数时候我们不会直接给图示命名,而是直接说“以下几张图交换”;如果我们需要特别提及——譬如在定义极限和余极限时——某张图示,记为 $\mathfrak{F},\ \mathfrak{G}$

Haskell 部分

在 Haskell 语言中存在大量与范畴论对应的概念,然而,Haskell 代码没有自然语言文档这样丰富的样式,因此有必要约定清楚这些对应关系,尽量避免符号误用和混淆:

  1. 原则:所有文档中的 Haskell 概念都使用等宽字体 \texttt 或 \mathtt
  2. 特例:对于Hask 范畴和Hask 范畴上的自函子范畴这两个特殊概念,Haskell 语言的代码中不会显式提及它们,因此我们仍然沿用数学概念的记号 $\mathcal{H}$ 和 $\mathrm{Endo}(\mathcal{H})$
  3. 范畴论中的对象,对应 Haskell 中的类型 (type),用 $\mathtt{a,\ b,\ c,\ a1,\ a2}$ 等表示任意类型,即 Hask 范畴 $\mathcal{H}$ 中的任意对象;极少数时候,我们会提及具体的类型,例如 $\mathtt{Bool,\ Int}$ 等
  4. 态射对应 Haskell 中的函数 (function),用 $\mathtt{f,\ g}$ 等作为函数名,指代某个具体的态射,而函数类型签名体现了这个态射的源对象 (domain) 和目标对象 (codomain),例如:
    $$\mathtt{f\ ::\ a\ \to\ b}$$
    这个函数签名表示“名为 f 的函数接受类型为 a 的输入同时输出类型为 b ”,对应到范畴论的概念上,即“态射 $f$ 将源对象 $A$ 指向目标对象 $B$ ”
  5. 函子对应 Haskell 中的类型构造器 (type constructor),例如 Maybe 和 [];必须特别注意,我们也会用 $\mathtt{f,\ g}$ 表示任意函子,我们尽力避免函子与态射的记号相互混淆,但我们无奈地承认这种可能性,读者必须根据上下文自行甄别——尤其是出现对象映射时,读者必须提高警惕;函子的态射映射 $\mathfrak{f}(h)$ 在 Haskell 中对应 fmap h :: f a -> f b,其中态射 $h$ 的类型签名为 h :: a -> b
  6. 自然变换在 Haskell 上非常有趣,我们通过一个参数多态 (polymorphism) 的 Haskell 函数——这里随意命名为 eta ——来表示函子 f 到函子 g 的自然变换:
    $$\mathtt{eta\ ::\ forall\ a.\ f\ a\ \to\ g\ a}$$
    用范畴论的视角看,参数多态的 Haskell 函数其实并非一个单独的态射,而是以任意对象 $\mathtt{a}$ 为参数的一族态射 $\eta$,取参数 $\mathtt{a} = A$,得到其在对象 $A$ 上的分量为 $\eta_{A}$ ——这恰好是自然变换的定义!
  7. 积在 Hask 范畴上对应元组 (tuple) (,) ,即 $\{\mathtt{(a,\ b),\ fst,\ snd}\}$,对应的态射运算为 f &&& g;而余积则对应 Either ,即 $\{\mathtt{Either\ a\ b,\ Left,\ Right}\}$,对应的态射运算为 f ||| g 或 either f g

体例

这份讲义的目标是建立以下三者的联系:

  1. 范畴论
  2. Haskell 编程语言
  3. 现实中可以被抽象出来的典型计算过程和数据关联

瞄准目标,我们将以结构化的方式引入每一个范畴论概念。首先从直观的实例和隐喻开始,为读者建立必要的直觉。随后尝试严格化,分别使用两种视角定义并认识这个概念,即数学家的视角和 Haskell 程序员的视角。接着我们会加入更系统、更完整的 Haskell 代码实例,帮助读者进一步实现概念接地。最后,每个概念会附上 5-10 道习题。

强调数学家视角和程序员视角的差异与联系,这是本讲义贯彻始终的母题。我们坚持向读者传递这种思维方式,即对于范畴论的同一概念。数学家和程序员分别选择了“更趁手”的界面或接口(interface)。简而言之,两套接口内核一致,只是表象不同。我们将会看到,得益于 Haskell 优雅的设计,两套接口在基本概念上几乎完全一致,但对于一些进阶概念,二者之间确实存在差异,这里举一例:

对于保持了源范畴之幺半结构的函子,范畴论——即数学家的接口——使用“弱幺半函子”这个名字,而 Haskell 语言——即程序员的接口——使用 Applicative 类型类。弱幺半函子要求我们提供一个单位态射 $\phi_0$ 和一个自然变换 $\phi_1$,用于说明函子如何保持原范畴的幺半结构;而 Applicative 要求我们实现 pure 和 <*> 两个函数。乍看上去,二者是如此不同,但我们会证明两套接口可以互相实现,因此它们是等价的。

关于“如何对待数学证明”,本讲义采取的态度是:如非特别强调,默认只在 Hask 范畴 $\mathcal{H}$ 下证明定理,且只证明那些对行文逻辑必不可少的定理,毕竟这不是一本范畴论教材——那将严重偏离我们的写作动机和目标。如果可能,我们首先考虑以 Haskell 代码的形式组织证明——尤其是证明各种同构,在 Haskell 代码中,这等价于要求我们实现两个方向的函数。

内容安排

下面列出的大纲非常粗糙,为了抓住灵感,有些地方甚至不成句子,请读者见谅。后续更新的内容将按大纲分节展开。

范畴、对象与态射

范畴的定义,对象与态射的定义,Hask 范畴下的类型与函数。作为开篇,要提醒读者注意到范畴论的“世界观”,即不再关注对象的“内部结构”,转而研究“外部相互作用”,即将注意力放在态射上。放在 Hask 范畴中,这即是要求读者暂时忽略类型的值——当然同时也忽略函数的具体实现——专注于函数的类型签名。

后面我们会构造一个例子,从最简单的 $\mathtt{Bool}$ 类型入手,向读者展示从“内部视角”迁移到“外部视角”并不会丢失任何信息,不会损失语言的表达能力,其核心想法是,我们可以把类型 T 的“值” v ,v :: T,看成是某种特殊记号(语法糖),等价于从单位对象出发的态射,v :: () -> T,而内部视角下的“值” v 可以看作这个态射的唯一签名。

函子:范畴间的变换

函子的定义,Haskell 中的类型构造器。Maybe,[],并介绍一个特殊的例子 (->) s,即固定入参类型的函数作为函子,也叫指数函子。若非特别强调,“函子”其实是“协变函子”的简称,对应某种生产容器,其态射映射对应后处理。

逆变函子(选读)

逆变(contravariant)函子(选读,首次可跳过),对比 (->) s 与 Op s,前者是协变函子,等价于 (s -> *),后者是逆变函子,等价于 (* -> s);逆变函子的运算 contramap :: (b -> a) -> f a -> f b,也记为 g >$< (f x);逆变函子对应某种消费容器,其逆变态射映射对应预处理。

自然变换:函子间的变换

函子的自然变换,本节开始带领读者识别并分析交换图。我们会提供一对漂亮的实例,用 safeHead :: [a] -> Maybe a 构造一个 [] 到 Maybe 的自然变换,而反向并不构成自然变换,因此两个函子不是自然同构。本节还会介绍两个自然变换的竖直复合与水平复合。

积与余积:组合对象的两种方式

积和余积,积 (product) 在 Haskell 中对应的是 $p_1 = \texttt{fst},\ p_{2}=\texttt{snd}$,$a \times b = \texttt{(a, b)}$ 以及 $\left<f,\ g\right> = \mathtt{f\ \&\&\&\ g}$ 。注意,积特指笛卡尔积,是更一般的张量积 (tensor product, $\otimes$ ) 的特例。顺便介绍对偶的概念,将 $z,\ a,\ b,\ a \times b$ 的整张交换图反过来,就可以得到余积 $\{a+b,\ i_{1},\ i_{2}\}$,在 Haskell 中对应 $\{\mathtt{Either\ a\ b},\ \mathtt{Left},\ \mathtt{Right}\}$,态射映射为 $\left<f,\ g\right> = \mathtt{f\ |||\ g}$

极限与余极限(选读)

选读内容,极限 (limit) 与 余极限 (colimit)。我们所熟悉的终对象、始对象、积和余积在该定义下成为极限与余极限的特例。在 Haskell 中有终对象 () 以及对应的唯一态射族 const () :: a -> (),作为对偶,还有始对象 Void 和对应的唯一态射族 absurd :: Void -> a。对于包含两个对象且无态射的图示,其极限为积,余极限为余积。

此外,对于图示中存在态射——即存在约束或相互作用——的情况,我们简要介绍等化子 (equalizer)、推出和拉回,同时提醒读者注意,由于 Haskell 中缺乏像 Idris 一样强大的依赖类型,我们难以在 $\mathcal H$ 中表达复杂的极限概念,这是 Haskell 类型系统的局限性。

幺半范畴

幺半范畴 (monoidal category),结合子 $\alpha_{ABC}$ 以及左右单位子 $\lambda_A$ 和 $\rho_{A}$,它们都是自然变换,且满足由交换图给出的五边形公理和三角形公理。作为延申,提及 Mac Lane 严格性定理 (Mac Lane’s coherence theorem),该定理告诉我们,定义中无需引入更复杂的交换图,只要满足三角形公理和五边形公理,任何由结合子与单位子组成的自然变换图都交换。

笛卡尔闭范畴

笛卡尔闭范畴 (Cartesian closed category, CCC),大略上,拥有这种性质的范畴 $\mathcal C$,对于任何态射类 $\mathrm{Hom}_{\mathcal C}(A,\ B)$ ,都能找到相应的对象 $B^A \in \mathrm{Ob}(\mathcal C)$ 与之同构,即 $B^A \cong \mathrm{Hom}_{\mathcal C}(A,\ B)$。称 $B^A$ 为指数对象,它象征着 $\mathcal C$ 能够在其内部表示“从 $A$ 到 $B$ 所有态射”这个概念,而无需诉诸集合范畴 $\mathrm{Set}$。在 Haskell 中,指数对象 $B^A$ 恰是我们熟悉的函数类型签名 a -> b 。

我们经常听到在函数式语言中函数是一等公民,所谓“一等公民”,意思是说函数也是对象,自然也有自己的类型。现在我们看到,笛卡尔闭范畴正是“一等公民”的理论基础,它赋予了“一捆”态射作为对象的新身份,这也是一种新视角,是函数式语言强大表达能力的基石。

作为对比,延伸材料中简单提及对称幺半范畴 (symmetric monoidal category, SMC),它比笛卡尔闭范畴更弱,用于建模资源有限的过程,在编程语言中对应线性类型。对称幺半范畴没有对角态射 $\Delta\ :\ A\to(A,\ A)$ 和丢弃态射 $!\ :\ A \to ()$,故所有类型无法复制无法丢弃,能且只能使用一次。

幺半群对象

幺半群对象 (monoid object),特别强调,其幺半结构并非随意定义的,而是完全从该对象生活的幺半范畴中继承——大部分教程都没有重视这一点!那些有 SICP 基础的读者,熟悉 accumulate 的概念,更会想当然地认为:对象上的幺半结构是人工随意赋予的,是“一个点上局部的结构”,与来自范畴的宏观结构无关——这是严重狭隘和错误的认识!我们明确指出这一点,对下文中引入 Applicative 和 Monad 的概念非常有帮助。

准确地说,我们所熟悉的“幺半群”,其定义中要求一种二元运算,我们可以自由访问该运算的第一个参数和第二个参数——这仿佛是天经地义的废话。我们特别强调,对象之所以具有这种性质,绝非“免费”得来,而是继承了范畴的幺半结构——由 (,) 诱导的笛卡尔积幺半结构。为了深化理解,我们构造一个“反向”的世界,即通过 Either 诱导的余积幺半范畴,我们会在这种情形下观察幺半群对象的行为,它非常古怪,能给读者留下深刻印象。

弱幺半函子与 Applicative

弱幺半函子 (lax monoidal functor),保持源范畴上的幺半结构,在 Haskell 中对应 Applicative,用于合并相互独立的子计算。数学家习惯的接口是 unit :: () -> f () 和 strength :: (f a, f b) -> f (a, b),程序员习惯的接口是 pure 和 <*>,注意我们可以用 {fmap, unit, strength} 实现 {pure, <*>},反之亦然,因此二者等价。

自函子范畴上的幺半群对象与 Monad

自函子范畴上的幺半群对象,“压平”嵌套的函子,在 Haskell 中对应单子 Monad,用于串联互相依赖的子计算。数学家习惯的接口是 unit :: a -> f a 和 join :: f f a -> f a,而程序员习惯的接口是 return / pure 和 >>=,同样,二者等价。作为延申,可以提一下 Kleisli 范畴与 Monad 的联系。

Freyd 范畴与 Arrow(选读)

选读内容,第一次阅读可跳过,Freyd 范畴和 Arrow,这是一种介于 Applicative 和 Monad 之间的抽象。

伴随函子

伴随函子 (adjoint functors),两个自函子 $\mathfrak{f},\ \mathfrak{g}$ 伴随,记为 $\mathfrak{f} \dashv \mathfrak{g}$ ,这要求 $\mathrm{Hom}(\mathfrak{f}(a),\ b) \cong \mathrm{Hom}(a,\ \mathfrak{g}(b))$。

作为例子,可以证明 (->) s 是 (s, ) 的伴随,而证明所依赖的双射就是 curry 和 uncurry;恒等函子也是 Maybe 函子的伴随。作为伴随函子最有趣的性质,如果 $\mathfrak{f} \dashv \mathfrak{g}$,那么 $\mathfrak{g} \circ \mathfrak{f}$ 则“免费”生成一个 Monad,即我们自动从同构中得到两个自然变换,对单位变换有:

$$\mathtt{unit}_{X}\ :\ X\ \to\ \mathfrak{g} \circ \mathfrak{f}\ (X)$$
对“压平变换”有:
$$\mathtt{join}_{X}\ :\ (\mathfrak{g} \circ \mathfrak{f}) \circ (\mathfrak{g} \circ \mathfrak{f})\ (X) \to\ \mathfrak{g} \circ \mathfrak{f}\ (X)$$
我们也提供一些合成 Monad 的例子:积函子 (s, ) 与指数函子 (->) s 复合而成的 monad 是 (s, ) -> s ,在 Haskell 中称为 State monad,而恒等函子和 Maybe 函子生成的就是 Maybe monad;[] monad 也由类似的伴随函子生成而来。总而言之,伴随函子反映了函子间深刻的结构关联与优良的性质。在对偶情形下,用 $\mathfrak{f} \circ \mathfrak{g}$ 可以生成一个余单子 (comonad),我们所熟悉的 State monad,其对偶的 comonad 是 (s, (->) s),在 Haskell 中称为 Store comonad,也称 costate monad,下文中的 lens 库正是建立在这种结构上。

范畴论的世界观:实例研究

插入小节,本节尝试通过实例探讨范畴论的世界观,即“外部视角”。本节尝试构造一系列与 Bool 类型相关的态射和对象,实现了完整的逻辑运算。读者将会清晰地认识到,不依赖内部的“值视角”,而是转向外部的“态射视角”,我们同样可以还原 Bool 类型的全部行为,范畴论的抽象并没有丢失任何信息。核心构造:定义两个态射 true :: () -> Bool 和 false :: () -> Bool,加入 not :: Bool -> Bool、and :: (Bool, Bool) -> Bool 等态射,配合相应的交换图用以约束这些态射的行为。我们还介绍一种(思维观念上的)语法糖,即“值-类型” val :: a 可以看成范畴幺元 () 到对象 a 上的态射 val :: () -> a,在这种对应关系下,内部视角的“值”可以看作这种态射的唯一标识;类似地,可以将函数 f 加载实参 val 后的输出 f val :: b 看作态射复合 f . val :: () -> b,对多参数函数可以类似处理,不再赘述。在延伸内容中,可以额外提一提终对象 (terminal object) 和全局元素 (global element) 两个概念。

透镜与棱镜:解析 lens 库

Profunctor Optics 和 lens 库,Control.Lens.Prism,它是 Haskell 生态系统中最重要的工具,设计极尽工巧。此刻,读者已经掌握了足够的范畴论概念,本节中我们会展示这些概念的威力,全面剖析 lens 的设计思想和实现,我们会看到它事实上是一个 Costate comonad,源于指数对偶,任何笛卡尔闭范畴都能自动生成这样的 comonad。这也许是整份讲义中最优美、最普适的代数结构,我们期待本节内容能为读者带来审美和智识上的双重趣味。

米田引理

米田引理 (Yoneda lemma),广义元素 (generalized element) ,依赖类型(Haskell 中不支持),本节是范畴论内容的最后一块拼图,也是这份讲义在形式上的结尾。

尾声:形式化的边界

尾声,选读内容:形式化的边界。上述内容让读者体会到了范畴论优雅而精密的结构,也见证了范畴论与 Haskell 语言相结合带来的强大抽象能力。但是,写在最后,读者请务必意识到,所谓 Hask 范畴并不是一个真正的范畴!

表面上看,这是因为 Haskell 语言的一些病态性质,例如底 (bottom,记为 $\bot$ ) 的存在,导致并非每个 Haskell 函数都能输出它所“承诺”的类型。一方面,使用偏函数会让我们很快感知到 $\bot$ 的影响,例如 head :: [a] -> a,当列表为空时它会报错,而非输出我们约定好的 a 类型;另一方面,即使我们避免使用偏函数——遵循 Haskell 社区的忠告——我们很快[6]会意识到这并非一个简单的“编码规范”问题,绝不是你换成 safeHead :: [a] -> Maybe a 就能轻松绕行——事实上要深刻得多,它直接与停机问题相关。

哥德尔不完备定理说明,我们永远不可能把形式化推向极致,即便我们自信满满地通过 Maybe 或 Either 安置了所有异常,我们也许忽略了更基本的问题:我们的函数真的会停止吗?它能在有限的时间内输出一个我们约定的类型吗?谁负责证明?从停机问题——作为一切可计算问题的终点,也是形式化的终点——往回看,一个宏大的真相缓缓显出轮廓,即语言的表达能力和类型系统的精度在超过某个临界点后会相互制约。

现实中的编程语言必须在二者间找到平衡,这个话题还可以充分延伸下去,衔接到更为现代的函数式语言,例如 Idris 2 和 Lean 4,但那将远远超出这份讲义最初划定的概念边界。接下来的旅途,我们将方向盘交还给读者,读者已经掌握了所有必要的知识,接受了充分的训练,是时候开始一番激动人心的自由冒险了!


  1. 此事在《人月神话》中亦有记载,一般作为“没有银弹”的补充说明。 ↩︎

  2. 指 GPT 3.5 公开的时间点,在那之后,一切面向文本输入输出的工作都在日渐失去价值。这个说法最早可以追溯到知乎用户@酱紫君,我非常认同。 ↩︎

  3. 除了库霸王,我似乎看不出有任何一个角色关心碧姬公主,我甚至怀疑,有些通关了很多代正作的人第一次知道碧姬公主是在《马里奥赛车》。 ↩︎

  4. 由于我不是计算机系科班,而 SICP 是我的编程启蒙读物,导致 Scheme 甚至是我的母语——或者换句话说,我在启蒙阶段就是一个学杂了的双语者,Python 和 Scheme 都是我的母语。我无法确定 SICP 多大程度塑造了我今天的思维,那是我进入这个世界的第一扇门。十年前,我抬头看到门楣上刻着铭文,抽象与隔离,有一个声音一遍一遍问我准备好了吗,我迫不及待地推开那扇门,隆隆声扬起一阵呛人的灰尘,然后我意识到门后是什么——现实世界汹涌的复杂性。后来我逐渐明白,那铭文是一则咒语,我们用肉体凡胎试图理解——并对抗——比我们强大亿万倍的复杂性,那是唯一的法术。 ↩︎

  5. 人的工作记忆大约只能容纳 $7 \pm 2$ 个区块 (chunks),怎样组织区块的内容并控制区块的数量,这直接决定我们能处理多复杂的问题。 ↩︎

  6. 出于巧合,某天你初次尝试定义某种“有限规模的容器”作为一个类型,你定义了若干操作,尝试让编译器帮你证明这些操作都保持你的容器有限。起初一帆风顺,但当你偶然写下某种递归操作,你突然察觉到编译器表现出一些怪异的行为,接着你开始反思,是不是你设计的类型定义有问题,也许你漏掉了什么——随着你反复迭代,你潜意识中怀疑一切背后也许有什么神秘的东西,似乎是某种你暂时说不清楚的限制,并非 Haskell 语言给你的限制,而是比那更宏大、更深刻、更接近某种事物的本源——你不知道如何表达这种感受,于是你开始搜集资料,终于,你看到了这份讲义。 ↩︎

迈尔斯·戴维斯自传

第一章

谈起少时岁月,我所记得最早的事物是一束火焰。有人点燃煤气炉,一束蓝色的火焰跳了出来。我不记得那人是谁了,也许当时是我在摆弄炉子,这不重要。我深深为之震撼,一束蓝色火焰自炉头嗖一下窜出来,那猝然一瞬。那是我能追溯到最远的记忆;更久远的过去是一团迷雾,你知道的,是谜。而那火焰,在我脑海中却像音乐般清晰。那年我三岁。

我注视着那束火焰,感受它的热量传到脸上。我感到恐惧,真正的恐惧,它第一次出现在我的人生中。可我也记得,那像一场冒险,一种诡异的快感。我猜,那段经历将我带往意识中一个不曾步至的地方,带往所有可能性的边界——也许如此。我也不知道,此前我从未试着厘清这一切。那恐惧更像在鼓励我,鼓励我径直走进某种我一无所知的东西。我想正是那里,我的人生哲学发源于此,我开始投身于我所信奉的一切,就在那一刻。我不知道,但我觉得大概就这样。我他妈那时候懂个屁。我始终坚信,打那时起,我只能一路前行,远离那束火焰的热量。

回顾过去,我并不记得自己一岁时的事——何况我也不喜欢回忆过去。但我确切知道一件事,在我出生一年后,一场剧烈的龙卷风袭击了圣路易斯城,撕碎了一切。对此,我好像还零星记得什么——在我记忆深处。也许,这解释了我的脾气为何如此暴躁;那场龙卷风将它狂暴的创造力留在我体内。也许,它还留下一阵强风。你懂,吹小号需要强风[1]。从神秘且超自然的意义上,我坚信如此,况且龙卷风显然足够神秘,足够超自然。

我出生于 1926 年 5 月 26 号,伊利诺伊州阿尔顿市。阿尔顿是个河滨小城,位于密西西比河上游,东圣路易斯市以北 25 英里。我继承了父亲的名字;而他继承了他父亲的。于是我叫迈尔斯·杜威·戴维斯三世,但家里所有人都称呼我小迈。我一辈子都讨厌这小名。

我父亲来自阿肯色州。他在一座农场长大,那属于他父亲,迈尔斯·杜威·戴维斯一世。我祖父是个会计,干这行得心应手,他为白人做账,赚了很多钱。世纪之交,他在阿肯色州买下五百英亩土地。当他买完土地,附近的白人,那些曾雇佣祖父为他们梳理财务问题、整理账本的白人,转而排挤他,将他驱离自己的土地。依他们的认知,黑人不该拥有所有土地、所有财富。他不该聪慧过人,甚于白人。这一切并没有多大改观,哪怕在今天,依旧一切如昨。

在我一生多数时候,来自白人的威胁笼罩着祖父的生活。他甚至派自己的儿子,也就是我的叔叔弗兰克,当他的保镖,以期避开这些威胁。戴维斯家族一马当先,父亲和祖父如是说,而我对他们深信不疑。他们说戴维斯家都是独树一帜的人——艺术家、商人、专家、音乐家——旧日里为种植园主奏乐,早在蓄奴制度废止前始终如此。到我祖父为止,戴维斯家祖辈都演奏古典音乐。这也导致我父亲既不弹也不太听音乐,蓄奴制度结束了,祖父曾说,“他们只准黑人在破酒馆和窑子里演出。”他的意思是他们——那些白人——再也不想听到黑人演奏古典音乐;他们只想听黑人唱唱灵歌和布鲁斯。如今,我不知道这有多大程度属实,但父亲告诉我的就是这样。

父亲还告诉我,祖父曾告诫他,每当他拿到一笔钱,无论何时何地,无论从谁手里,一定要点清数额,看看齐了没有。他说在金钱方面信不得任何人,哪怕是自家人。有一回,祖父给父亲一笔钱,说有 1000 美元,让他带去银行。银行远在 30 英里外。户外阴凉处也有 38 度 [2]——阿肯色州的夏日。父亲一会步行,一会骑马,可算到了银行,父亲点了一遍钱,只有 950 美元。他又数了一遍,一模一样的数额:950 美元。他几乎吓尿了裤子,连忙赶回家,跑到祖父跟前,说他丢了 50 美元。祖父只是站在那儿,看着他说,“你走之前数过钱吗?齐了吗?”父亲说没有,他走之前没数过钱。“那就对了,”祖父说,“因为我只给了你 950 美元,你什么都没丢。但我跟你说过吧?把钱点清楚,任何人的钱,包括从我这。给你 50 美元,点清,然后到银行把钱存进去,照我说的做。”对于整件事,能让你牢牢记在脑子里的,不光是远在 30 英里外的银行,还有那傻逼天气,热得发癫。祖父在这件事上着实冷酷,但有时你必须冷酷。父亲从未忘记这一课,他还将这一课传给了孩子们。所以现在我会数清每一分钱。

我父亲,以及我母亲,克莱奥塔·亨利·戴维斯,都于 1900 年出生在阿肯色州。他在那儿读了小学。父亲和他的哥哥妹妹都没上中学,而是跳过去,直接进了大学。父亲毕业于阿肯色州浸会学院、宾夕法尼亚州的林肯大学,还有西北大学的牙科学院,因此父亲获得了三个学位。印象中,在我长大一点的时候,我抬头在他办公室墙上看到了那些傻逼玩意儿,我说,“我操,他可别让我弄这些。”我还记得一张照片,父亲在西北大学的毕业照,上面只有三副黑人面孔。他二十四岁那年从西北大学毕业。

他哥哥,斐迪南,上了哈佛和某所柏林的大学。他比父亲大一到两岁,跟父亲一样,他也跳过了中学。他高分通过入学考试,直接进了大学。他这人棒极了,整天给我讲凯撒和汉尼拔的故事,还有黑人历史。他环球旅行,走遍天涯海角。他脑袋比我父亲更好使,同时是个情场高手,还是一份杂志的编辑,名叫《色彩》。他是那么聪明,让我觉得自己是个傻子;在我成长过程中,只有他能给我带来这种感觉。斐迪南叔叔远不止这些。我喜欢围着他转,听他讲旅行的故事,讲他的女人。他还巨他妈时髦。我在他身边晃悠得太频繁,甚至惹怒了母亲。

父亲从西北大学毕业后娶了母亲。她会拉小提琴,也弹钢琴。她的母亲在阿肯色州当风琴老师。她从未提过太多她父亲的事,所以我不太清楚她老家的情况,她没说过,我也没问过。我也不知道为什么。从我听到的只言片语推测——当然,也考虑到我见过其中一个人——她的家族大概是中产阶级,态度里流露着一丁点傲慢。

母亲非常漂亮。她时髦到夸张,长着一副南亚人面容,就像卡门·麦克雷,还有深棕色的光滑皮肤。她颧骨很高,头发带着印度人的质感,还有双美丽的大眼睛。我和哥哥弗农长相都随她。她穿貂皮大衣,戴钻石;她浑身上下光彩照人,戴各式各样的帽子,以及别的玩意儿,在我看来,母亲的朋友们都和她一样光彩照人。她的穿着打扮总是极尽奢华炫目。我继承了母亲的长相,也继承了她的衣品,还有对潮流的敏感。我猜,你可以说我身上一切艺术天赋都来自母亲。

不过我和她相处并不算太融洽。也许这是因为我们彼此都有坚强而独立的人格。我们仿佛争论不休。我爱母亲;她不是凡夫俗子。她甚至不会做饭。但是,我说了,我爱她,即便我们并不亲密。关于我的人生轨迹,她有一套自己的规划,而我也有。哪怕在小时候,我也一直践行自己那一套。我猜你可以说我和母亲更相似,胜过父亲,纵使我也从他那继承了一些东西。

父亲一开始在伊利诺伊州阿尔顿市安家,我和妹妹德罗茜在那出生,随后我们举家迁至东圣路易斯市,


  1. 原文两处用的都是 strong wind,双关语,可以理解为“吹小号需要强劲的气息”。 ↩︎

  2. 原文中是 100 华氏度,为方便阅读,这里转换为摄氏度,约为 37.8 摄氏度。 ↩︎

天要下雨,随他去罢

华盛顿哥伦比亚特区

透过椭圆形办公室的落地窗向外望去,奔流的雨水在草坪上汇集成水洼,又被烈风卷向天空,夏日的暴风雨正在席卷北美大陆东北部。远处的安德鲁斯空军基地,两架亮着绿色编队灯的战斗机刺破雨幕,顶住横风,挣扎着维持进近航道。那是两架返场的F-35A,今天最后的波次,受极端天气影响,安德鲁斯空军基地终止了所有航空作业。

叮铃铃铃,叮铃铃铃——橘黄色的大手拿起红色的话筒,贴到耳边,“Hello, this is the president.”

电话来自夏威夷,第 15 太空监视中队,一位年轻的太空军少校,名叫 Gabriel Moore,圣经中传来好消息的天使。

“Mr. President, we have an unsanctioned launch. I repeat, an unsanctioned launch from Cape Canaveral. Falcon 9 carrying a Crew Dragon. Trajectory indicates— indicates a transpacific injection. We believe the occupant is Elon Musk.”少校语速快得惊人,有点上气不接下气。

特朗普总统从未意识到话筒如此容易变形,塑料材质的话筒,他听见话筒和自己的指节一起咔咔作响。还有窗外,暴雨痛击地面的声音,夹杂着狂风撕扯树冠的声音,那颗木兰树的树冠,杰克逊总统两个世纪前亲手栽下的木兰树。

壁炉上方挂着众先贤的画像,正中央是乔治·华盛顿,一头整齐的银发,鲜衣怒马。向右数两幅,富兰克林·罗斯福坐在办公桌后,一手执笔,面无表情地注视着坐在同一张办公桌后的特朗普总统。总统起身,目光穿过椭圆的长轴,逐一投向墙上的每一位总统,期望得到答案。

没有回答。

“Hello? Mr. President?”话筒中传来少校焦急的声音。

此刻,历史将选择权交给他,唐纳德·特朗普,合众国第 47 任总统。

“The capsule is on a sub-orbital trajectory. It will re-enter the atmosphere over the Western Pacific in approximately 70 minutes. The Navy has assets in the area. We need your order, sir, what are the rules of engagement?”少校催促着。

那是他最好的朋友——曾经是。暴风雨更大了,远方传来雷鸣。总统转身,猛地打开落地窗,狂风抓起桌面上散落的文件,狠狠抛向天花板,墙上的画框纷纷被掀翻在地,砰然作响。在四散飞舞的纸页中,总统终于开口了,声音低沉而疲惫。

“Well, just—just let 'em go while it’s raining outside.”

佛罗里达州

三十分钟前,肯尼迪航天中心 LC-39A 发射工位旁停着一辆特斯拉皮卡,盛夏的骄阳把不锈钢车身烤得滚烫。也许这辆车停得过分近了,安全条款禁止如此。从不远处的飞行控制中心望去,皮卡模糊的银灰色影子受地表的热浪折射,晃动着,像是隔了一块缓慢熔融的玻璃。

猎鹰九号火箭伫立在工位上,它的一子级已经回收复用了七次,箭身被燎成邋遢的炭黑色;顶端的载荷是龙飞船 C212.4 自由号,雪白的外壳光洁如初,很难相信它此前执行过四次天地往返任务,同托举它的火箭一样久经沙场。依发射计划,下周一自由号会飞往国际空间站,执行它的第五次任务。

火箭周遭弥漫着白茫茫的雾气,箭体外壁甚至结了霜,与酷热的环境格格不入。

“最后一次合练不是前天就结束了吗?燃料都泄回了吧?”一名身穿 NASA 黑 T 恤的工程师揉着眼睛,怀疑自己出现了幻觉。“头儿又心血来潮加了一场?”

“我看了日程表,今天没安排,是不是液氧管路出问题了?”另一位同事放下手里的咖啡,凑到窗边。

“等等——上帝啊,那是埃隆的车!他们在加注燃料!埃隆——埃隆人在哪里?”

恐慌如同闪电般掠过飞行控制中心。大屏幕上的数据显示,39A 工位的燃料管路处于打开状态,超低温的液氧和煤油正疯狂泵入猎鹰九号的贮箱。这不是演习,更不是故障。

“切断燃料供应!快!”任务主管嘶吼着,却是徒劳,控制台返回了红色的 ACCESS DENIED。

“系统被锁死了!有人从内部接管了最高权限,我们被踢出来了!”

“安保!安保在哪里?未授权的发射!重复一遍,未授权的发射!”

几辆福特探索者冲向发射台,可已经来不及了。半路上远远望去,特斯拉皮卡的车门忽然打开,一个穿着 SpaceX 宇航服的人影下车,隔着头盔上黑色的面罩,监控看不清他的面容。但他走路的姿态,那种笨拙却坚定的步伐,所有人都认得出来。

埃隆·马斯克。

他没有回头,径直走向了发射塔的乘员升降机。在他身后,还有一位身穿宇航服的船员,身形像是初中年龄的小孩,手里拎着一个手提箱。

“他在飞船里!他把自己关进去了!”

“是自动发射程序!他启动了倒计时!”

控制中心内,人们眼睁睁地看着屏幕上鲜红的数字跳动。这枚身经百战的火箭,此刻像一头被唤醒的巨兽,周身喷吐着寒气,准备将它的主人送往一个无人知晓的目的地。

“… 5, 4, 3, 2, 1, 0. LAUNCH—”

九台梅林发动机喷出烈焰,狂暴的声浪和冲击波滚滚而至,控制中心的地面震动着,玻璃嗡嗡作响。固定火箭的爆炸螺栓应声脱离,猎鹰九号拖出一条壮丽的火龙,决绝地刺向佛罗里达湛蓝的天穹。那不是任何 NASA 预设的轨道,在爬升到一定高度后,火箭执行程序转弯,径直飞向西方。

那辆被遗弃的特斯拉皮卡,在火箭尾焰的炙烤下,不锈钢外壳迅速变成蓝紫色,卷曲,变型,最终被气浪掀翻,像一个孩子丢弃的玩具。

西太平洋

“Captain on the bridge!”值更官喊出口令。

舰长 Wexler 上校疾步跨进舰桥,匆匆向值更官[1]回礼。他刚睡下不到三个钟头,就被 CIC[2] 打来的紧急通讯叫醒。DDG-105,美国海军杜威号导弹驱逐舰,当前正处于灯火管制,在西太平洋漆黑的海面上航行着。

舰桥内,舱壁被显示器微弱的亮光晕出一抹朦胧的暗红,而舷窗外笼罩着一片如墨的夜色,好像那片凝固的黑色本就是舰体的一部分。大海很少像今晚这样柔和,风平浪静,站在舰桥感受不到一点摇晃,杜威号仿佛在无边夜幕中悠然滑行。

舰长感到一种梦境般的不真实。航海钟显示现在舰上时间是凌晨三点一刻,这不过是一次普通的 FONOPs 任务,战术官[3]那种语气是怎么回事?最佳拦截位置?这只是一艘独立部署的驱逐舰,谁的命令?哪个疯子敢拦截中国的航天器?一觉醒来,这下轮到杜威号点燃世界大战了?

舰长抬头,看向综合显示器,雷达锁定的目标自东向西飞行,轨道高度 170 公里——这时,数据链传来红外预警卫星捕捉的完整轨道信息——不对,不是中国,发射位置竟然是佛罗里达州,卡纳维拉尔角!

突然,套住目标的红色小方框右上角出现一行跳动的数字:

00:15:00
00:14:59
00:14:58

那是宙斯盾系统自动计算的拦截倒计时。

“TAO, ID the bogey.”舰长慢慢恢复了脚踩地面的实感,思维清晰起来。

“Sir, track is designated UNK-2025-S757917-Alpha. Launch detected from Florida. Profile matches a Crew Dragon. No squawk, no flight plan—this is an unsanctioned launch. It’s on re-entry, but on an atypical trajectory. Looks like it’s aimed at a specific splashdown point.”战术官的声音有些干涩,听筒里一并投来 CIC 嘈杂的背景音,口令响成一片。

“A specific point? Where?”

“Aye, sir. Projected splashdown is in the South China Sea.”

舰桥的空气似乎凝固了。南海,这个词像一枚深水炸弹在每个人的脑海里引爆。一枚从美国本土发射,未经授权的航天器,目的不明,即将闯入世界上最敏感的海域。

“And our orders from the C.O.C.?”上校追问。

“Negative, sir. We’ve pinged PACFLT three times. The only word back is Stand By.”

“Stand by? ”舰长吼了出来。“What the hell kind of order is that? The Aegis engagement clock isn’t going to Stand By!”

“Captain, T-minus ten minutes to intercept window.”战术官提醒道,他的手指悬停在武器释放按钮上。“The Aegis recommends autonomous engagement, sir.”

上校死死盯着屏幕上那个代表着龙飞船的方框。它像一颗流星,正一往无前奔向自己的命运。

“Maintain the firing solution,”他最终开口,声音决绝,“NOBODY touches that console until I give the command.”

“Aye aye, sir! Holding the lock, waiting on your command. Two SM-3s are hot and ready.”

前甲板下方,两枚标准-3型反导拦截弹开始上电自检,红外导引头启动制冷。倒计时仍在继续,杜威号穿过浓稠的夜色,向西驶去,前往拦截窗口的最佳位置。

菲律宾

巴拉望岛的夜空格外纯净。渔夫劳尔收起今天最后的渔网,躺在螃蟹船窄小的船舷上,准备抽完一根烟就睡下。海风带着咸腥的暖意,轻抚着他的脸庞。

突然,东方的天际亮了起来。

不是流星。流星是一闪而过,纤细而优雅。而那东西,是一团巨大的,燃烧的火球,拖着长长的、不断分裂的尾迹,无声地划过天鹅绒般的夜幕。火球的颜色在橙红和诡异的翠绿之间变幻,那是金属在超高温下熔融、汽化的颜色。

劳尔惊得坐了起来,嘴里的香烟掉进了海水里,滋拉一声响。

那团大火球在空中解体了。像一朵在极致高度绚烂绽放的烟花,分裂成几十个、上百个更小的火球,每一个都拖着自己的火尾,组成了一场壮观而诡异的流星雨,覆盖了半个天空。它们不是坠落,更像是燃烧殆尽,在抵达海面之前,就化作了夜色中最后的余烬。

村子里传来几声犬吠,但很快又归于平静。劳尔怔怔地望向天空,直到最后一丝光亮消失。他不知道那是什么,或许是天上的神明在巡游。

他凝视着这场沉默的、盛大的、史诗般的葬礼,划了个十字,默默祈祷着明天的渔获。

尾声

龙飞船没有留下任何可供辨认的残骸。

美国海军联合中国、越南、菲律宾等多国海军,在推算的溅落区域展开了持续数月的搜索,最终只找到几块无法确定来源的、高度烧蚀的复合材料碎片。它们可能来自龙飞船,也可能来自任何一颗再入大气的人造卫星。

白宫发布了一份语焉不详的声明,称 SpaceX 公司在一次“无人试验任务”中遭遇“严重异常”,导致飞行器失联。声明中没有提及埃隆·马斯克的名字。此后,特朗普总统在任何场合都再未提起过他。

埃隆·马斯克,就此从世界上消失了。

他死了吗?死在了那场撕裂天穹的绚烂解体中?绝大多数人相信如此。

但真相果真如此吗?

阴谋论开始在互联网的暗流中滋生。有人声称,飞船解体是伪造的,是马斯克用某种障眼法,金蝉脱壳,成功抵达了目的地。有人言之凿凿,说在中国西北的某个秘密科研基地里见到了他。一位日本网友自称曾服役于海上自卫队,说自己曾任 DDG-179 摩耶号的雷达官,他说那个夜晚的确有军舰发射了反卫星导弹,但不是杜威号,从雷达特征上看,那枚导弹甚至根本不是标准-3。

最离奇的说法是,马斯克压根没去中国,而是执行了他的终极计划——龙飞船和早已等候在近地轨道的星舰对接,飞往霍曼转移轨道,成为那颗红色星球上孤独的创世者。

真相被永久封存在了西太平洋数千米深的海底,还有一部分在大气层中化为等离子体的烈焰。

至于杜威号的舰长 Wexler 上校,任务结束后,他被调往五角大楼的一个文职岗位,多年后官拜海军中将。不过,Wexler 将军再也没有回到海上,他从不谈论那个夜晚的经历。认识他的人都说,他时常会望着西边的天空,一看就是几个小时。


  1. OOD,当舰长不在舰桥时,代为管理舰桥的军官。舰长返回舰桥时,值更官必须大声喊出口令,将指挥权交还舰长。 ↩︎

  2. 战术信息中心,导弹驱逐舰上综合管理传感器与武器的舱室,是驱逐舰的大脑,重要性超过舰桥。 ↩︎

  3. TAO,战术信息中心(CIC)的主管军官。 ↩︎

菲茨杰拉德短篇选译:资助芬尼根

作者:F. 司各特·菲茨杰拉德 (1896-1940)

一

芬尼根和我有同一位文学经纪人,负责为我们推销作品。虽然我经常在芬尼根刚离开或即将到访时出现在坎农先生的办公室,却从未见过他本人。我们的出版商也是同一家,每当我到那时,芬尼根通常刚刚离开。从他们提到他的语气中——

“啊,芬尼根——”

“哦,是的,芬尼根刚才在这儿。”

——我隐约感到,这位杰出作家的来访并不平静。某些话暗示着他离开时带走了什么东西——我猜是手稿,是他那些畅销的伟大小说中的一部。他带走的是需要做最后润色的部分,据说他会反复修改十次,以达到那种流畅自然、机智幽默的风格,而这正是他作品的标志。不过,我逐渐发现,芬尼根的大多数拜访都与钱有关。

“很遗憾你要走了,”坎农先生会告诉我,“芬尼根明天要来。”然后,经过一番若有所思的停顿,“我恐怕得花些时间陪他。”

我不知道是他声音里的哪种腔调,让我想起曾与一位紧张不安的银行行长谈话,当时有报道说迪林杰[1]就在附近。他的目光望向远方,像是在自言自语:

“当然,他可能会带来一份手稿。他正在写一篇小说,你知道的,还有一部戏剧。”

他说这话时,好像在谈论某个文艺复兴时期的事件,有趣,但遥远;不过紧接着他补充了一句“或者也许是篇短篇小说”,他的眼神变得更有希望了。

“他应该很有才华吧?”我说。

“哦,是的,”坎农先生振作起来,“他什么都能做到——只要他下定决心。从来没有过这样的人才。”

“我最近没怎么看到他的作品。”

“哦,但他正在努力工作。有些杂志社还压着他的稿子呢。”

“压着稿子等什么?”

“哦,为了更合适的时机——等到行情好转的时候。持有芬尼根的作品总是一件令人骄傲的事。”

确实,芬尼根的名字就像金子铸成的一样。他的职业生涯一开始就光彩夺目,尽管后来未能持续保持最初的辉煌,但每隔几年,他都会重新焕发光彩。他是美国文坛上永远被寄予厚望的人——他运用文字的本领着实惊人,字句闪耀,迸发光彩——他写出的句子、段落、章节,无一不是精工细织的杰作。直到我遇到某个可怜的编剧,他正试图把芬尼根的一本书改编成逻辑连贯的故事时,我才意识到芬尼根也有他的敌人。

“读起来一切都很美,”那人厌恶地说,“但当你把它整理清楚时,感觉就像在疯人院待了一周。”

从坎农先生的办公室出来后,我去了第五大道上的出版商那里,很快得知芬尼根明天也会来。事实上,他尚未露面,声势已如此浩大,以至于我原本打算用来讨论自己作品的午餐会,大部分时间都围绕着芬尼根展开。我再次感觉到,我的东道主,乔治·贾格斯先生,与其说是在跟我讲话,不如说是在自言自语。

“芬尼根是个伟大的作家,”他说。

“毋庸置疑。”

“而且你知道,他其实人挺好的。”

既然我并未质疑这一点,我便问是否对此有过疑虑。

“哦,没有,”他急忙说。“只是他最近运气实在太差了——”

我同情地摇了摇头。“我知道。跳进半空的游泳池那次真是倒霉透顶。”

“哦,那不是半空的。泳池是满的,满满的。你应该听听芬尼根讲这个故事——他能把它说得让人笑破肚皮。他说自己当时状态不好,只是从泳池边随便一跳——”贾格斯先生用刀叉指着桌子示意,“然后他看见几个年轻女孩从十五英尺高的跳板上跳下去。他说他想到了自己逝去的青春,于是也爬上去,做了一个漂亮的天鹅跳——但肩膀在空中就断了。”他有些焦虑地看着我,“你听说过类似的情况吗?比如棒球运动员扔球时脱臼?”

我一时想不出任何类似的骨科案例。

“然后,”他梦呓般继续说道,“芬尼根不得不在天花板上写作。”

“在天花板上?”

“差不多吧。他没有放弃写作——那家伙很有胆量,虽然你可能不信。他让人做了个什么装置,悬挂在天花板上,他就仰面躺着,在空中写字。”

我不得不承认,这安排确实需要勇气。

“那影响他的作品了吗?”我问道。“你是不是得像读中文那样倒着读他的故事?”

“有一阵子是挺混乱的,”他承认道,“但他现在好了。我收到了他几封信,听起来更像是过去的芬尼根了——充满了活力、希望和对未来的计划——”

他脸上又露出那种恍惚的神情,于是我转而谈论更贴近我内心的话题。直到回到他的办公室,这个话题才再次浮现——我写下这段文字时不禁脸红,因为这涉及到一件我很少做的事:偷看别人的电报。事情是这样的,贾格斯先生在走廊里被人拦住了,我走进他的办公室坐下时,那封电报就摊开在我面前:

有五十块我至少能付打字费理个发买点铅笔生活已难以为继我靠着好消息的梦想苟延残喘急盼 芬尼根

我简直不敢相信自己的眼睛——五十美元?!而且我恰好知道芬尼根的短篇小说稿费大约是三千美元。乔治·贾格斯找到我时,我还呆呆地盯着那封电报。他看完后,眼神惊恐地看着我。

“我不知道该如何心安理得地这么做,”他说。

我愣了一下,环顾四周,确认自己还在纽约那个繁荣的出版商办公室里。然后我明白了——我误解了电报内容。芬尼根要的是五万美元预付款——这样的要求足以让任何出版商措手不及,不管对方是谁。

“就在上周,”贾格斯沮丧地说,“我刚给了他一百美元。每个季度我的部门都会因此亏损,所以我不能再告诉合伙人了。我自掏腰包——牺牲一套西装和一双鞋。”

“你是说芬尼根破产了?”

“破产?!”他看着我无声地笑了起来——说实话,我不太喜欢他笑的样子。我哥哥也有神经质的笑声——但这是题外话。过了一会儿,他恢复了镇定。“你不会跟别人说吧?其实芬尼根这几年接连遭遇挫折,但他现在正在摆脱困境,我相信我们会收回每一笔——”他试图找个词,但“给他的钱”脱口而出。这次轮到他急切地转移话题了。

别误会,芬尼根的事情并没有占据我在纽约的那一整周——但不可避免的是,在代理商和出版商的办公室里频繁出入时,我还是了解了不少。例如,两天后,我在坎农先生的办公室用电话时,不小心接到了他和乔治·贾格斯之间的一段对话。这只能算部分偷听,因为我只听到了一方的讲话,而这总比听到全部好。

“……但我记得他身体还不错……几个月前他倒是提到过心脏有问题,但后来听说好了……哦,他还谈到一个手术,好像是癌症……嗯,我当时真想告诉他我也打算做个手术,要是负担得起的话早就做了……不,我没说。他当时情绪很好,我不想打击他。他今天开始写一篇新故事,还在电话里念了一部分给我听……

“……我确实给了他二十五块,因为他口袋里一分钱都没有……哦,是的,我相信他现在没问题了。听起来他准备大干一场。”

我现在完全明白了。这两个人已经默默达成了一种默契,彼此互相安慰关于芬尼根的事。他们在芬尼根身上的投资——对他未来的期望——已经累积到如此巨大的数额,以至于芬尼根几乎成了他们的财产。他们无法忍受听到任何关于他的负面评价——甚至来自他们自己。

二

我坦率地对坎农先生说:“如果这个芬尼根是个骗子,你不能无休止地给他钱。如果他完了,那就是完了,没有什么可做的。你因为他的事推迟了自己的手术,而他却在外面跳进半空的游泳池,这真是荒谬。”

“泳池是满的,”坎农耐心地纠正我,“满满的。”

“不管是满的还是空的,我觉得这人就是个麻烦。”

“听着,”坎农说,“我马上要和好莱坞通电话。与此同时,你可以看看这个。”他把一份手稿扔到我腿上。“也许它能帮你理解。他昨天带来的。”

那是一篇短篇小说。我一开始带着厌恶的心情阅读,但不到五分钟,我就完全沉浸其中,彻底被它吸引,并且暗自感叹上帝,希望自己也能写出这样的作品。当坎农结束电话时,我让他等着,直到我读完。当我抬起头时,作为一个身经百战的职业作家,我的眼中竟噙满泪水。全国任何杂志都会毫不犹豫地将其放在头条发表。

不过,从来也没有人否认芬尼根会写作。

三

几个月后,我再次来到纽约。这一次,在我的代理商和出版商的办公室里,世界似乎变得更加安静、稳定。终于有了时间谈论我那些认真但缺乏灵感的文学追求,去乡下拜访坎农先生,或者在夏日夜晚与乔治·贾格斯一起消磨时光,彼时纽约的星光垂直而下,像闪电般坠入餐厅花园。至于芬尼根,他远得像是在北极——事实上,他确实在那儿。他带了一支队伍,包括三位布林莫尔学院的人类学家,听起来他可能会收集到很多素材。他们打算在那里待上几个月,如果这件事听起来像是一场有趣的家庭聚会,那大概是因为我的嫉妒和偏见。

“我们都很高兴,”坎农说,“这对他是天赐良机。他厌倦了这里的生活,正需要这样的——这样的——”

“冰天雪地,”我补充道。

“是的,冰天雪地。他临走前的最后一句话非常符合他的风格。无论他写什么,都将纯净如雪——会有耀眼的光芒。”

“我可以想象。但是告诉我——谁资助的这次旅行?上次我来的时候,我感觉这人已经破产了。”

“哦,他真的很体面。他欠我一些钱,我想也欠乔治·贾格斯一点——”他“想”,这个老伪君子。他明明很清楚——“所以在他离开之前,他把大部分人寿保险转让给了我们。以防他回不来——毕竟那些旅行很危险。”

“确实危险,”我说,“特别是和三个女学生一起去。”

“所以我和贾格斯完全不用担心万一发生什么——就这么简单。”

“保险公司资助了这次旅行吗?”

他明显不安地动了动。

“哦,没有。事实上,当他们知道这笔款项的原因时,有点不安。乔治·贾格斯和我认为,既然他有一个具体计划,并且最终会有一本书,我们有理由再支持他一步。”

“我不明白,”我直截了当地说。

“你不明白?”他又露出疲惫的眼神。“好吧,我承认我们犹豫过。原则上我知道这是错的。我过去偶尔会给作者预支小额款项,但最近我已经制定了规则禁止这样做——并且一直遵守。过去两年里只破例过一次,是为一个处境艰难的女作家——玛格丽特·特拉希尔,你认识她吗?顺便说一句,她是芬尼根的老相好。”

“请记住我甚至不认识芬尼根。”

“说得对。等他回来你一定要见见他——如果他还回得来的话。你会喜欢他的——他魅力十足。”

我再次离开纽约,前往我内心想象中的北极,时光流转,夏天和秋天悄然过去。十一月,第一丝寒意沁入空气,我带着一丝寒颤想起了芬尼根的探险队,所有对他的嫉妒都消失了。他带回来的任何战利品,无论是文学上的还是人类学上的,大概都是他应得的。然而,当我回到纽约不到三天时,我从报纸上读到,他和几位团队成员在食物耗尽后走入了一场暴风雪,北极又吞噬了新的牺牲者。

我为他感到难过,但也很庆幸坎农和贾格斯得到了妥善保护。当然,芬尼根尸骨未寒——如果这样的比喻不算太过悲惨——他们并没有谈论此事,但我了解到保险公司已经放弃了“人身保护令[2]”或他们行话里的类似条款,看来他们拿到赔偿金是板上钉钉的事了。

他的儿子,一个英俊的小伙子,在我待在乔治·贾格斯办公室时走了进来。从他身上,我能猜到芬尼根的魅力所在——一种羞涩的坦率,伴随着一种印象:他内心正进行着一场非常安静而勇敢的战斗,他无法完全说出口——但在他的作品中却像热烈的闪电般显现出来。
“这孩子也写得很好,”乔治在他离开后说,“他带来了一些出色的诗。他还没准备好接替他父亲的位置,但绝对有前途。”

“我能看看他的作品吗?”

“当然,这是他刚留下的。”

乔治从桌上拿起一张纸,打开,清了清嗓子。然后他眯起眼睛,稍微弯下腰坐在椅子上。

“亲爱的贾格斯先生,”他开始读,“我不愿当面跟您提这个请求——”他停了下来,眼睛迅速扫视着后面的内容。

“他要多少?”我问。

他叹了口气。

“从他给我的印象,我还以为这是他的作品,”他痛苦地说。

“但这就是他的作品啊,”我安慰他。“当然,他还不太能接替他父亲的位置。”

我后来很后悔说了这话,毕竟芬尼根已经还清了他的债务,而且能活着真好,现在好时光又回来了,书也不再被视为不必要的奢侈品。许多我认识的作家在大萧条期间勉强维生,如今终于实现了长期推迟的旅行、还清了抵押贷款,或者创作出了只有在一定的闲暇和安全感下才能完成的更为精致的作品。我刚刚收到了一千美元的好莱坞预付款,准备带着旧日的激情飞往西海岸,那时候“家家锅里有鸡吃[3]”。我去找坎农告别,顺便领这笔钱,很高兴发现他也从中受益——他邀请我去看一艘他打算买的摩托艇。

但最后一刻有些事情耽搁了他,我等得不耐烦,决定先走一步。敲了几次门没人回应,我干脆推开了他办公室的门。

里面的办公室显得有些混乱。坎农先生同时接了好几个电话,正在向速记员口述关于保险公司的事务。一个秘书正匆忙戴上帽子穿上外套,像是要去执行任务,另一个则在数着钱包里的钞票。

“只要一分钟,”坎农说,“只是办公室里有点小骚动——你从未见过我们这样。”

“是芬尼根的保险吗?”我忍不住问,“它失效了?”

“他的保险——哦,完全有效,完全没问题。这只是为了尽快筹集几百块钱。银行关门了,我们都在凑份子。”

“我刚拿到你给我的那笔钱,”我说,“我去西海岸用不了这么多。”我抽出两张百元大钞。“这些够吗?”

“太好了——这简直就是救命钱。没关系了,卡尔森小姐。梅普斯夫人,您不用去了。”

“我得走了,”我说。

“再等两分钟,”他恳求道,“我只需要处理一下这份电报。这是个好消息,会让你振奋的。”

那是一封来自奥斯陆的电报——在我开始读之前,心里充满了预感。

奇迹般安全抵达此地但被当局扣留请电汇四人路费外加两百块我正带回丰硕成果来自死者的问候。

——芬尼根

“是的,这真是个好消息,”我附和道,“他一定有很多故事要讲了。”

“他当然会有,”坎农说,“卡尔森小姐,给那些女孩的家长发电报——最好也通知贾格斯先生。”

几分钟后,当我们走在街上时,我看到坎农先生似乎被这突如其来的消息震撼到了,陷入了沉思,我没有打扰他,毕竟我不认识芬尼根,也无法全心分享他的喜悦。他沉默的情绪一直持续到我们走到摩托艇展的门口。就在招牌下,他停下脚步,抬头望着,仿佛第一次意识到我们要去哪里。

“哦,天哪,”他说,退后一步,“现在进去也没用了。我以为我们要去喝一杯。”

我们确实去喝了一杯。坎农先生仍有些恍惚,完全沉浸在巨大的惊喜中——他在掏钱付账时摸索了好久,我坚持让我买单。

我想他当时整个人都处于迷糊状态,他是一个极其细致准确的人,可我在他办公室递给他的那两百美元从未出现在他寄给我的账单中。不过,我相信总有一天我会拿回来,因为总有一天芬尼根会再次成功,我知道人们会争相阅读他的作品。最近,我主动调查了一些关于他的传闻,发现大多数都是假的,就像那半空的游泳池一样虚假。那个游泳池其实是满的,满满的。

到目前为止,关于那次极地探险只出了一篇短篇小说,是个爱情故事。也许这题材没有他预期的那么宏大,但电影界对他感兴趣——如果他们能先好好观察他一番,我有充分的理由相信他会挺过去的。他最好能挺过去。

发表于《时尚先生》(Esquire)杂志
1938 年 1 月


  1. Dillinger,著名银行劫匪。 ↩︎

  2. Habeas Corpus,法律概念,指要求将某人带至法庭以判断其拘留是否合法的法律程序或令状。 ↩︎

  3. A chicken in every pot, a car in every garage. 美国前总统胡佛在 1928 年的竞选口号。 ↩︎

无声的咆哮

突然,雷达屏幕上所有目标都消失了。

时间一分一秒地过去,屏幕刷新了一次又一次,却始终毫无变化,不再出现任何光点,平静如水,仿佛刚才的嘈杂和骚动只是一场幻觉。令人不安的寂静一点一点灌满房间,每个人后背都泛起一丝凉意,这不寻常,大家都明白。徐上尉熟悉这种感觉,他在美国空军交流的时候见证过。那是七年前,他刚从陆军官校[1]毕业不久,一个万里挑一的机会砸中他,飞去内华达州的内利斯空军基地,作为学员旁观“红旗”军演[2]。

徐上尉站起身,透过窗户向西边望去,海天相接的地方被夕阳染成一片眩目的橙红,秋水共长天一色,只是没有孤鹜。除了落霞和秋水,徐上尉的眼前只剩一条柔和的地平线,空无一物,海水慵懒地摇曳着,像是要在这个祥和的黄昏沉沉睡去。他眯起眼睛,把目光集中在晚霞上,努力想象着,想象他的视线可以穿过云层,看到两百多公里外的天空。

一幅清晰的画面浮现在徐上尉的脑海中,那是一架“侧卫”家族的战斗机[3],双座型,通体涂成浅灰色,背朝夕阳,安静地拖出一条长长的冷凝航迹。与制空挂载的“侧卫”不同,这架战斗机的翼尖挂架没有挂格斗弹,取而代之的是两个安装了刀状天线的设备舱;同样,它的翼下和机腹挂点挂了四个电子对抗吊舱,没有中距弹。它似乎不屑于炫耀武力,就这么平稳而孤高地向东飞着,机身边缘闪烁着暖红色的辉光。空旷的天幕下,它的身影显得犹为孤独,或者说,那其实是一种目空一切的傲慢。忽然,它轻轻摆了摆机翼,优雅得像是孔雀抖落尾羽上的露水。

雷达已经沉默了半个小时,或者更久。徐上尉收回想象,面前的大海和记忆中内华达州的沙漠交织在一起。这窒息的静谧,这升腾而起的压迫感,他太清楚一切的缘由——这是电子战飞机君临战场的征兆。在数百公里外,三万七千英尺的高空,那厚厚的云层背后,年轻的君王在活动筋骨,它无声地咆哮着,昭告天下,它的旨意奔腾呼啸,传遍秋日的天空,传遍这座小岛上每一部雷达和通信终端:

Veni Vidi Vici

不知怎的,在这种时候,徐上尉居然想起了自己在美国的太平日子。“红旗”军演结束后,他得到两周假期。他飞去洛杉矶,租了一辆老款丰田卡罗拉,沿着一号公路飞驰,饱览加州壮丽的海岸线。那是一个同样令人心醉的黄昏,红日西斜,徐上尉握着方向盘,朝左一扭头就能看到海面,徐徐浪涛映出夕阳的余晖,泛着琥珀色的点点光芒。车刚开出 Big Sur 不久,极目远眺,华灯初上的 Santa Cruz 小城倒映在蒙特雷湾上,如同一串闪闪发光的水晶项链。车里的电台放着耳熟能详的民谣,The Sound of Silence,清冷的男声正唱出那句歌词:

And no one dared
Disturb the sound of silence

天色渐暗,年轻的君王仍在看不见的地方俯视众生,咆哮着,纵情展露它的威严。君王从不亲自持剑,它对杀戮毫无兴趣,生来只为统治。万籁俱寂,仅仅因为它命令如此。在这个夜晚,新王加冕的夜晚,属于它的夜晚,它定义整片天空的法则,无人胆敢忤逆它。

这是徐上尉守着雷达的第五年。此刻晚霞已经完全消失了,天边的云层展现出本来的面目,那是深灰色的积雨云,厚重地连成一片,仿佛正在为电闪雷鸣积蓄能量。海面没有一丝风,徐上尉长久地眺望云层,感到有些喘不过气,一定是气压降低的缘故。

暴雨将至,他想。


  1. 中华民国陆军军官学校,台湾武装力量培养陆军军官的军事院校,校址设在台湾省高雄市,前身为黄埔军校。 ↩︎

  2. 美国空军举办的先进空战训练演习项目,一年三次,为期两周,于 1975 年 11 月 29 日首次举行,汇集了来自美军四个军种以及美国军事盟约国人员演练。 ↩︎

  3. 这一段是徐上尉的幻想,是一架在开战首日执行全面电磁压制任务的歼 16D 电子战飞机。 ↩︎

一些最近很喜欢的俳句

打年初开始,各种社交平台随处可见各式各样的俳句,无厘头中又透着令人欲罢不能的趣味。俳句的创作规则很简单,就是三个句子,每句的音节按 5-7-5 排列。 中文是单音节语言,凑音节的难度几乎可以忽略,加上俳句本身就是很生活化、很随意的体裁,进一步降低了网友们参与俳句创作的门槛。

一首典型的俳句像是这样:

先是五个字

再写七字加五字

这就是俳句

小红书的当代俳句

细读一些作品,被网友的智慧深深吸引,有些作品完美还原了了松尾芭蕉的细腻和小林一茶的诙谐。文学果然是每个人的文学,中国人还是太全面了。

先看一首松尾芭蕉式的俳句,来自小红书用户“在课桌上刻下一个草字”:

春雨大如瓢

奶茶饮半放窗台

半杯变一杯

动态、季节元素、平和而质朴的语言、抓人的剧情,我愿称草老师为当代徘圣!

再来一首关于猫咪的俳句,来自小红书用户“老山羊拄拐”:

路遇小猫咪

呼唤不应好奇怪

是个垃圾袋

写每个人生活中共通的小趣味,精准还原俳句的内核,山羊老师堪称亚圣。

英文俳句

回到稍微严肃一些的话题,英语国家对俳句的喜好和追捧非常出乎我意料。早在上世纪 60 年代,创作英文俳句逐渐在美国文学圈流行开来。在俳句运动的参与者中,不乏耀眼的名字,例如杰克·凯鲁亚克:

Snow in my shoe—
Abandoned
Sparrow’s nest.

我很喜欢这首,它复刻了日文俳句的神貌,用精致的视角关注那些细微的东西,同时在语言上不加雕琢,仿佛一个缓慢的拉镜头,用空镜诉说着细腻的故事。

类似的还有佩妮·哈伍德(Penny Harwood):

First autumn morning:
the mirror remains fogged
with her absence.

也许是文化和民族性格的原因,英文俳句占比更大的是另一种风格,相比日文俳句见微知著的素雅,英文俳句似乎偏好更宏大、更瑰丽的意境。我很喜欢其中两首,后文附上个人拙译,尽力用 5-7-5 的汉字重现原作的氛围。

第一首出自美国黑人作家理查德·赖特(Richard Wright):

Whitecaps on the bay:
A broken signboard banging
In the April wind.

我的翻译:

白浪覆海湾

听斑驳标牌响彻

料峭四月风

这首的意象很具体,大体上是一个推镜头的描写,动态也很简单,通过排列组合这些基础元素塑造一幅早春的画面,翻译过来几乎没有损失。

第二首出自英国诗人詹姆斯·柯克普(James Kirkup):

In the amber dusk
Each island dreams its own night
The sea swarms with gold.

这首太过绝妙,尤其是第二句,带着迪士尼动画般的梦幻与美好,还有詹姆斯·乔伊斯式的想象力,我看到它立刻想到了卡尔维诺说的“一切故事的原点”。

我很想把它翻译成中文,我确实尽力尝试了,但结果实在难以令我满意,我把草稿放在这里,盼望看到更好的译文:

琥珀暮光下

星罗岛屿渐入梦

海涛点点金

隐含波动率与有效场论

BSM 期权定价模型用几何布朗运动(GBM)刻画标的资产的价格变化,其噪声项 $W$ 是维纳过程,事实上没有体现市场的长尾特性 [1],看起来 BSM 只是一个理想模型。

$$dS = \mu S dt + \sigma S dW $$

在金融实践中,我们往往直接将期权的价格代入 BSM,反向求解出波动率。对不同的期限 $T$ 和行权价 $K$,我们都可以求得一个波动率,称之为隐含波动率(Implied Volatility, IV)。对于市场上所有合约,隐含波动率构成一张曲面 $\sigma(K, T)$。

$$C = S_0 N(d_1) - K e^{-rT} N(d_2) $$
$$d_1 = \frac{\ln \frac{S_0}{K} + \left( r + \frac{\sigma^2}{2} \right) T}{\sigma \sqrt{T}} $$
$$d_2 = d_1 - \sigma \sqrt{T} $$

因为噪声的影响,将原始价格数据中反求的 IV 直接插值为曲面不是一个好主意。我们不妨先把来自不同合约的 $(\sigma_i, K_i, T_i)$ 视作零散的数据点,从最大后验概率估计(MAP)的视角下理解这个问题:波动率曲面应该是某种意义上的平均或者说平滑,同时满足一些约束条件。金融直觉告诉我们,约束中理所应当要包括无套利条件。其次,我还希望曲面是光滑的。有了这些约束条件,我们就可以把数据点代进来,解一个优化问题,最后得到一张波动率曲面(Volatility Surface),它是一切期权交易者的生命。

波动率曲面

现在我们思考一个本质问题,固定波动率的 BSM 显然无法捕捉市场的长尾特性,这个“硬算”的波动率曲面来自 BSM,却又不符合 BSM 的基本假设,那么它到底是什么?它捕捉到了什么超越 BSM 的信息?

想想看,我们从一个“错误”的模型中,再做一次“错误”的处理,最后得到了某个看起来或许是某种平均的“可观测量”,我们希望依赖这个似是而非的可观测量洞察到“真实”的市场现象,这可能吗?

为了回答这些问题,我们把目光投向一些超越 BSM 的模型,例如 Merton(这位是 BSM 中的 M,是的,还是他)的扩散跳跃模型[2]。既然维纳过程没法建模长尾,那我们干脆加入一个随机的泊松跳跃。接着,我们可以推导出一个修正后的伊藤公式[3],得到扩散跳跃模型下的微分方程,最后得到定价公式。最妙的事情来了,Merton 模型的定价可以看作若干 BSM 定价的加权和!

理一理,Merton 跳跃扩散模型的表达能力确实比 BSM 强,但似乎并没有强很多,长尾不是什么天堑,我们甚至可以简单地利用 BSM 的线性组合来建模市场的长尾特征!沿着这个思路提出问题,BSM 要加上哪些额外的信息,才能获得与 Merton 跳跃扩散模型同等的表达能力?当然就是加权和的权重。

写到这里也许有读者已经看明白了,事实上波动率曲面就提供了这些额外的信息,它把短时程的跳跃平均成长时程的扩散,得到了一个“有效波动率(Effective Volatility)”。

我似乎已经回答了波动率曲面是什么的问题,但还没有解释为什么这种“错两次”的方法可行。

高能物理中早就出现过类似的事情,也就是“错两次”:有一个低能标(大尺度)的模型,要求得系统的某些性质,我们必须遍历所有的尺度求和,然而直接求和的时候,致命的问题出现了——这个代表系统某些性质的物理量居然会发散!聪明或者说绝望的物理学家们又发现,如果我们不遍历所有的尺度,而是在求和中截掉那些模型并没有覆盖到的尺度,同时调整模型的某些参数,最终奇迹般地得到一个正确的结果。

简单地说,低能标的模型并没有关于高能标细节的知识,这是第一个“错误”,截断到一个特定的尺度更没有道理,这是第二个”错误“,两个错误加起来却得到了正确的结果。

后来的物理学家用重整化群理论描述了这个惊人的现象,物理学家们认识到,场论永远都是一种有效理论(Effective Theory)[4]。在一个具体的有效理论下,一方面,我们永远无法知道高能标的细节,无法对高能标下的现象做出任何预言,但另一方面,也是最激动人心的地方,我们并不是什么都不能做!有效理论允许我们把高能标的细节——那些我们并不知晓的细节——平均到低能标的某些参数下,然后做出当前能标下有效的预言。

回到 BSM 和 Merton 扩散跳跃模型,波动率曲面可以视作一组“被重整”的参数,它反映了小尺度的扩散跳跃过程在大尺度上的平均作用,有效理论的又一次胜利,为之欢呼吧!

不想写了,就这么结束,感觉要说的点都提到了。


  1. 面对黑天鹅事件,你和你的模型一样可笑😅 ↩︎

  2. Merton R C. Option pricing when underlying stock returns are discontinuous[J]. Journal of financial economics, 1976, 3(1-2): 125-144. ↩︎

  3. Ito-Levy 公式,但 Merton 的原始论文中并没有这么做,他直接近似处理了泊松跳跃的效应。 ↩︎

  4. 有效理论是一个非常大的主题,背后蕴含着深刻的物理和哲学思想,这种思想帮助人类认识并理解任何层次化的复杂系统。举例而言,电动力学是量子电动力学的低能有效场论,几何光学是电动力学的低能有效场论,更进一步,计算机图形学又是几何光学的大尺度有效理论。在图形学中,我们通过微表面假设,把光与环境的相互作用平均到 BRDF 上,然后用 roughness map 和 normal map 等被重整的参数描述整个系统。在这个例子里,BRDF 就是有效模型,各种贴图是有效参数,光通量类似哈密顿量或是配分函数。这个主题很有意思,我打算专门写写。 ↩︎

市场的终点

有一个思考了一段时间的问题,我没法三言两语把题干说明白,所以先提一些基本概念。

理论上说,市场竞争总会把价格推向平衡点,在一个信息充分传播,市场参与者充分理性的前提条件下,市场应该是有效的,即当前资产的一切信息都已经体现在价格里,无论加入其他任何信息集,都无法对未来价格做出有效的预测。

金融实践上,市场远不是有效的,否则一切利用市场波动的套利策略都将不复存在。如果我们仿照平衡态统计物理的术语,把新信息出现到市场作出响应并达到有效(平衡点)花费的时间称为弛豫时间,股票市场的弛豫时间至少在分钟级以上。

但是,我是说但是,对于任何市场参与者,只要通过投机行为获利,事实上都在把市场推向更有效。例如高频交易者,专门捕捉极小时间尺度下的市场失效并从中获利,也就是在弛豫时间内获利。每一个获利的高频交易者都在帮助市场缩小弛豫时间,每个时间尺度下的策略容量都是有限的,先是那匹从滑铁卢赶回伦敦的快马,然后是电报,再后来是那些光纤直连华尔街的交易服务器,容量一点一点被吃掉,而市场也变得越来越有效。直到今天,我们甚至可以宣布,股票市场几乎是弱式有效的,技术分析的价值在一天天下降。

囿于过去几十年人工智能技术的发展——主要是表示学习(representation learning)——计算机在过去并不能接收并理解市场上的全部信息,场内交易数据是完全结构化的,因此计算机首先开发了基于场内数据的策略。随着充分竞争,最终这类策略的容量完全被消耗殆尽,市场在有金融意义的时间尺度下几乎进入弱式有效。

然而,人工智能技术在发展,transformer 出现后以及自监督学习出现后,表示学习几乎已经发展到了终点,今天的计算机可以用一套固化的流程理解几乎是任何模态的数据。

沿着这个视角,我们先考虑这样的简单情形,如果计算机可以理解非结构化的文本数据,那就意味着任何政策、财报、研报、新闻、舆情,即所有的基本面和消息面信息都能被计算机理解,作为某个交易模型的输入,很快这些策略的容量也会被计算机抢占一空,此时市场进入半强式有效。

再进一步,如果最终计算机可以直接接收并理解来自工厂、物流、仓库、销售的所有信息,市场将进入强式有效。

想想看,那是多么美妙、多么无聊的图景,市场变得完全有效,一切资产的定价都无比正确,整个市场不再需要人的参与,我们生活在一个由计算机自动定价的世界。

早就有人说过,在一个充分有效的市场下,任何主动买卖策略都没有意义,盈利的数学期望都有基线保持一致,因此买指数和 ETF 就足够了。

一个最终不需要人参与的完美市场,难道这就是资本主义的结局吗?

始于亨利·詹姆斯的现代恐怖故事

伍尔夫的爸爸曾经当过亨利·詹姆斯的编辑,伍尔夫一家人经常在客厅里听詹姆斯说那些华丽又晦涩的长句子,关系非常好。今天看到了一段伍尔夫写的评论,关于亨利·詹姆斯写的恐怖故事:

亨利·詹姆斯笔下的鬼魂与古老的暴力鬼魂——血迹斑斑的船长、白马、阴暗小巷和狂风中的无头女士——毫无共同之处。它们起源于我们自身。每当重要的事物超出我们的表达能力,每当普通的事物被奇怪的事物包围,它们就会出现。那些残留的令人费解的事物,那些挥之不去的令人恐惧的事物——这些都是他所捕捉、体现的情感,并使之成为一种安慰和陪伴。

原来现代恐怖故事是从詹姆斯开始的。布莱克伍德、洛夫克拉夫特,以及其他一切展现“不可名状的恐怖”的尝试,都源自詹姆斯。

笛安和福克纳

昨天和家属聊天,猛然想起来高中读过笛安的书,应该是《告别天堂》,当时就爱死了这种时间和人物交错的多线叙事。那本《告别天堂》应该是班上一位女同学的书,我那时候很喜欢,当然我是说那本书。我大概读了三四遍,然后把书还回去了。此后过了很长时间,十年甚至更久,我再也没有读过笛安的书。虽然我后来知道她慢慢出版了龙城三部曲,草草浏览一下,却总觉得找不到当年的兴致。

今年我读了福克纳,《我弥留之际》和《喧哗与骚动》,我隐隐觉得似乎在哪里见过这种叙事技巧,文章的结构也有种难言的熟悉。像是一个素未谋面的人,你第一眼看到他的脸,心里立刻涌起一个念头,潜意识告诉你他是你的老朋友,你此前已经在千万个场合接触过他的一切,只是你自己都没意识到。好吧,也许福克纳发明的技术潜移默化影响了每一本后世的小说,或许是我读过的,或许我没读过——我这样解释这种奇妙的熟悉感。

早上坐地铁回创新港,一路上找来笛安的访谈读了读,原来如此,谜底揭晓。笛安的爸爸就是作家,而他最喜欢的作家是福克纳,甚至写过一本像《我弥留之际》致敬的作品《无风之树》。高中时候,笛安受父亲的影响读了很多福克纳,照这么说,她第一部长篇小说有福克纳的影子也就再正常不过了。

细想一下福克纳式的技术,把故事拆成属于不同时间与角色碎片倒不是最难的,难的是每一个碎片要有自己的声音——福克纳毫无疑问做到了,而笛安大概做得不够好,《告别天堂》的四个叙事者其实只有两种声音。