6

我正在阅读Haskell 中的编程书籍并测试 GHCi 解释器中提供的示例。事实证明,IntGHCi 和 Hugs 解释器的类型行为存在差异。根据“Haskel 编程”的第 3 章,2^31 :: Int应该超出Int类型的范围。同时,在 GHCi 解释器中,我得到:

Prelude> 2^31 :: Int
2147483648

而在 Hugs 中,它的行为就像书中所说:

Hugs> 2^31 :: Int
-2147483648

在 GHCi 中,我什至可以检查结果是否为Int

Prelude> let x = 2^31 :: Int
Prelude> :type x
x :: Int
Prelude> x
2147483648

所描述的差异的根源是什么?我应该在 Hugs 中运行书中的示例还是使用 GHCi,这似乎是学习 Haskell 的推荐选择?我会很感激你的帮助。

4

3 回答 3

20

IntHaskell 中的 An必须至少支持的范围[-2^29 .. 2^29-1],但也可以更大。确切的大小将取决于您使用的编译器和您所在的架构。(您可以在2010 Haskell 报告中阅读更多相关信息,这是 Haskell 语言的最新标准。)

在 64 位机器上使用 GHC,您将拥有一系列[-2^63..2^63 - 1]. 但即使在 32 位机器上,我相信 GHC 给你的范围也会比严格的最小值(大概[-2^31..2^31 - 1])大一点。

maxBound您可以使用and检查实际界限minBound

> maxBound :: Int
9223372036854775807

实现之间的差异出现是因为语言定义明确允许它们以不同的方式实现这些类型。就个人而言,我会继续GHCi记住这一点,因为GHC它是迄今为止您最有可能使用的编译器。如果您遇到更多的不一致,您可以在标准中查找它们或询问某人(就像这里一样!);将其视为一种学习经历;)。

该标准在这方面很灵活,允许不同的编译器和架构以不同的方式优化其代码。我假设(但不是 100% 确定)最小范围是在考虑 32 位系统的情况下给出的,同时还让编译器将底层 32 位值中的几位用于其内部目的,例如轻松区分来自指针的数字。(我至少知道 Python 和 OCaml 会这样做。)GHC 不需要这样做,因此它会根据其架构公开完整的 32 位或 64 位。

于 2014-11-13T22:38:47.220 回答
4

很可能您使用的是 64 位系统,其中Int有 64 位。

尝试这个:

Prelude> 2^62::Int
4611686018427387904
Prelude> 2^63::Int
-9223372036854775808
于 2014-11-13T22:37:29.387 回答
4

Int是机器大小的。所以在 32 位平台上,它会在 2 31处溢出。

$ ssh pi@192.168.0.3
Linux raspberrypi 3.12.28+ #709 PREEMPT Mon Sep 8 15:28:00 BST 2014 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Nov 11 12:58:20 2014 from 192.168.0.102
pi@raspberrypi:~$ ghci
GHCi, version 7.8.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> 2^31 :: Int
-2147483648

请注意,Haskell 报告实际上并没有具体说明Int应该有多大——正如 Tikhon Jelvis 所说,它只是保证可以处理 2 29。但是 GHC 确实使用了所有机器整数,这通常是最佳的性能和需求。

于 2014-11-13T22:39:26.527 回答