试图获得大数字时无法解释的无限循环
Unexplainable Infinite Loop when trying to get the big number
我试图找到现存最大的非浮点数。但是,以下 Haskell 代码在 GHCi 中不起作用:
head (reverse [1..])
我的电脑在计算结果时几乎死机了。我试图用数学归纳法证明,通过取递增数字列表的最后一个元素,我得到了所有数字中最大的一个。
head (reverse [1]) returns 1,这个列表的最大数
head (reverse [1..100]) returns 100,这也是最大的数。
我真的很困惑。我错过了什么?为什么会有一个看似无限的循环? (我等了5分钟才出结果)还有其他方法可以试试吗?
理论上,HaskellInteger
是完全无界的,所以没有官方的方法来得到最大的。在实践中,GHC(通常)使用 GNU GMP 库,它允许不完全无限制,但仍然 巨大 数字,每个 单个 数字占用大量计算机内存的一部分。
实际上,head (reverse [1..])
没有特别优化来避免在内存中逐渐构建整个数字列表,这意味着您的计算机将开始抖动并且 运行 内存很快就会耗尽。
您可以尝试 last [1..]
,这应该避免将整个列表保留在内存中,因为它可以被增量地垃圾收集。但即便如此,你也可以 运行 比宇宙存在的时间更长的评估,并且仍然永远不会到达终点。
正如评论中所建议的,对于许多类型 other 而不是 Integer
有一个明确的上限,您经常可以在重载 maxBound
,例如使用 64 位 GHCi:
Prelude> maxBound :: Int
9223372036854775807
(即便如此,使用 head (reverse [1::Int ..])
也不是一个好主意,我应该知道,因为当它锁定时我不得不重新启动我的机器。)
我试图找到现存最大的非浮点数。但是,以下 Haskell 代码在 GHCi 中不起作用:
head (reverse [1..])
我的电脑在计算结果时几乎死机了。我试图用数学归纳法证明,通过取递增数字列表的最后一个元素,我得到了所有数字中最大的一个。
head (reverse [1]) returns 1,这个列表的最大数 head (reverse [1..100]) returns 100,这也是最大的数。
我真的很困惑。我错过了什么?为什么会有一个看似无限的循环? (我等了5分钟才出结果)还有其他方法可以试试吗?
理论上,HaskellInteger
是完全无界的,所以没有官方的方法来得到最大的。在实践中,GHC(通常)使用 GNU GMP 库,它允许不完全无限制,但仍然 巨大 数字,每个 单个 数字占用大量计算机内存的一部分。
实际上,head (reverse [1..])
没有特别优化来避免在内存中逐渐构建整个数字列表,这意味着您的计算机将开始抖动并且 运行 内存很快就会耗尽。
您可以尝试 last [1..]
,这应该避免将整个列表保留在内存中,因为它可以被增量地垃圾收集。但即便如此,你也可以 运行 比宇宙存在的时间更长的评估,并且仍然永远不会到达终点。
正如评论中所建议的,对于许多类型 other 而不是 Integer
有一个明确的上限,您经常可以在重载 maxBound
,例如使用 64 位 GHCi:
Prelude> maxBound :: Int
9223372036854775807
(即便如此,使用 head (reverse [1::Int ..])
也不是一个好主意,我应该知道,因为当它锁定时我不得不重新启动我的机器。)