本文将概述 Haskell 里应用的一个概念,范畴论。因此 Haskell 代码的展示将会伴随其对应的数学定义,为了让读者可以直观地理解范畴论的概念以及它与 Haskell 的关系,这种对应可能不那么绝对的严谨。

范畴,本质上是一个简单的集合,包括三个组成元素:

范畴需要符合三条定律。第一条,也是最简单的一条,态射的组合操作需要满足结合律。

[1]上面的定律并不是一个十分准确的转换,因为我们忽略了下标。在 Haskell 中函数 id 是 多态的 — 它的域和范围可以采用许多不同的类型,用范畴的概念解释就是可以存在许多不同的源对象和目标对象。但是范畴论中的态射是定义为 单态的 — 每个态射都有一个特定的源对象和一个特定的目标对象(注意:这里的 单态 不在范畴论上使用)。多态 Haskell 函数可以通过指定其类型(用单态类型 实例化)来实现单态,因此我们说 Hask 上类型 A 的单位态射是 (id :: A -> A) 会更精确。(难度增加。)如果我们在上面的例子中添加另一个态射 h,如下图所示,它就不能成为一个范畴了。为什么?提示:从态射组合方面去考虑。