进一步滥用代数数据类型的代数 - 为什么这有效?

时间:2016-09-28 14:31:37

标签: haskell algebraic-data-types

所以我一直在阅读,如何在类似this SO questionthis 3 part series以及especially this等网页上将ADT转换为真实数字并操纵它们。

最后一个链接的“麻烦”部分引起了我的注意,我尝试在其中解决Nat,即使该文章指出它是不可能的。

Nat = 1 + Nat
Nat - Nat = 1
Nat(1 - 1) = 1
Nat = 1 / (1 - 1)

这可能看起来完全是胡说八道,因为我刚刚除以0(你可能是对的),但是如果你读了这些链接中的任何一个或类似的东西,那么你会注意到它看起来非常类似于a的定义列表。

List(x) = 1 / (1 - x)

所以你可以写出像Nat = List(1) = 1 + 1 + 1 + ...这样的Nat,这正是你在起始等式中重复替换所得到的。这也等同于在Haskell中定义像这样的自然数:

type Nat = [()]

这绝对是自然数字的有效编码,其中0 = []S(N) = () : N

所以我的问题是我怎么得到一个有效的结果呢?我刚刚除以零。更不用说起始等式本身就是一个矛盾。

那么为什么我会在最后得到一些有意义的东西呢?这只是纯粹的巧合还是在这个背景下以某种方式定义的0除法是否有意义?

1 个答案:

答案 0 :(得分:1)

由于Nat是无限的,因此您无法真正使用Nat - Nat = Nat ⋅ (1 - 1) = Nat ⋅ 0 = 0。差异Nat - Nat某些有限数,而Nat显然是无限的。所以这个1 - 1实际上并不为零,它在nonstandard analysis中更像是一个无穷小的值。如果你用无穷小的东西划分某些东西,你就会得到一些不同的东西(无限的,甚至是......),但是你并没有完全分裂为零。

事实上,我认为你所问过的悖论可以被视为“Nat无限的证明” - 因为如果它是有限的,你除以零。

除此之外,你无法通过这种类型的算术来证明 任何东西......这是一种有趣的消遣,但不是真正的数学。