-
首先这是类型范畴中的两个经典情况。左侧对应了类型 c 可以有两个态射分别到类型 a 和类型 b,右侧对应了类型 a 和类型 b 都有一个态射到类型 c。
-
实际上,在编程语言中,左侧对应了Pair<a,b> 的情况,右侧则对应了Eitherab 的情况。(好吧我 C++ 和 Haskell 混用一下)
同时,在数学中,左侧对应了∗ 的运算,右侧对应了+ 的运算。这怎么理解呢?
-
首先可以考虑两个特殊的类型:Unit 和Void。根据我的理解,type 就是值的集合,是范畴中的对象。而 Unit 就是只有唯一一个值的类型,Void 就是没有一个值的类型,分别对应了1 和0。
然后 pair 显然是有结合律的,即有Pair<a,Pair<b,c>>∼Pai<Pair<a,b>,c>,其中∼ 表示 isomorphism,是一一映射的。而 Either 也是有结合律的,于是我们可以把它们看作乘法和加法。实际上,这两个范畴是同构的。
Pair<a,Unit>∼a⇔a∗1=aPair<a,Void>∼Void⇔a∗0=0EitheraUnit=Lefta∣Unit∼Maybea=a+1EitheraVoid∼a=a+0
注意,a+1 就是我们的 Maybe,只不过构造子Just 其实就是Left,而只有一个值的类型Nothing 其实就是Unit。
-
所以再重申一遍:
(a,b)∼a∗bEitherab∼a+bUnit∼1Void∼0
于是我们可以用它来解非常厉害的东西。譬如:
L(a)=1+a∗L(a)
这是啥意思呢,其实可以转化:
Lista=EitherNil(a,Lista)=Nil∣(a,Lista)
其中Nil 也是只有一个值的对象,起到 Unit 的作用。我们发现,这个东西其实就是列表的定义。
通过解方程,有L(a)=1−a1=∑n=0∞an,所以:
Lista=1+a+a∗a+a∗a∗a+...=Nil∣a∣(a,a)∣((a,a)a)∣...
实际上就生成了列表类型。
-
最后说明下,其实 Unit 的同名有很多,后面不跟类型的类型构造子都可以看作 Unit,例如(Nothing,Nil 等)。但是 Void 一般只有叫 Void。