我一直在阅读有关将ADT转换为类似实数并进行操作的内容,例如这个SO问题,以及这个三部曲和特别是这个。
最后一个链接的“麻烦”部分引起了我的注意,尽管文章指出这是不可能的,但我仍然试图解决其中的Nat
问题。
Nat = 1 + Nat
Nat - Nat = 1
Nat(1 - 1) = 1
Nat = 1 / (1 - 1)
如果你读过那些链接或类似的内容,你会发现这个看起来非常像列表的定义。尽管我刚刚除以0可能看起来完全无意义(你可能是对的),但是请注意这点。
List(x) = 1 / (1 - x)
因此,您可以像这样编写Nat:Nat = List(1) = 1 + 1 + 1 + ...
,这正是在起始方程中重复替换所得到的。这也等同于在Haskell中这样定义自然数:
type Nat = [()]
这绝对是自然数的有效编码,其中 0 = []
,S(N) = (): N
。
那么我的问题是,我为什么能从中得到一个有效的结果?我只是除以了零。更不用说起始方程本身就是矛盾的。
那么我为什么在这个过程的末尾得到了有意义的东西?这只是纯粹的巧合还是0的除法在这种情况下被定义成有意义的呢?
1 != 1*1
,因此更正确的写法应该是Nat = 1 + 1*1 + 1*1*1 + ...
。 - chepner1
是*
的单位元。换句话说,对于任何x,都有x * 1 = 1
。因此,1
和1*1
是等价的。 - The Red Fox((), ())
与()
是不同的。x * 1 == x
是因为你可以无损地将值(a, ()) :: (x,())
转换为a :: x
,反之亦然。 - chepner