Why Int type 2^31 does not go outside the range in GHCi?
Asked Answered
A

3

6

I'm reading Programming in Haskell book and testing provided examples in GHCi interpreter. It turns out, that there is a difference in Int type behavior in GHCi and Hugs interpreter. According to Chapter 3 of "Programming in Haskel", 2^31 :: Int should go outside the range of Int type. Meanwhile, in GHCi interpreter I get:

Prelude> 2^31 :: Int
2147483648

while in Hugs it behaves just like the book says:

Hugs> 2^31 :: Int
-2147483648

In GHCi I can even check if the result is type of Int

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

What is the source of the described difference? Should I run the examples from book in Hugs or use GHCi which seems like to be recommended choice for learning Haskell? I will be grateful for your help.

Airstrip answered 13/11, 2014 at 22:33 Comment(2)
you should just uninstall hugsSteeple
@alternative: I think the hugs download should be taken down! Or maybe moved to an obscure location and protected by some kind of Haskell-specific CAPTCHA which needs detailed knowledge of the difference between Haskell98 and Haskell2010 to answer...Flanigan
G
20

An Int in Haskell has to support at least a range of [-2^29 .. 2^29-1], but it can also be larger. The exact size will depend on both the compiler you use and the architecture you're on. (You can read more about this in the 2010 Haskell Report, the latest standard for the Haskell language.)

With GHC on a 64 bit machine, you will have a range of [-2^63..2^63 - 1]. But even on a 32 bit machine, I believe the range GHC gives you will be a bit larger than the strict minimum (presumably [-2^31..2^31 - 1]).

You can check what the actual bound are with maxBound and minBound:

> maxBound :: Int
9223372036854775807

The differences between implementations come up because the language definition explicitly allows them to implement these types in different ways. Personally, I would keep on using GHCi just keeping this in mind, because GHC is by far the most likely compiler you will use. If you run into more inconsistencies, you can either look them up in the standard or ask somebody (just like here!); think of it as a learning experience ;).

The standard is flexible in this regard to allow different compilers and architectures to optimize their code differently. I assume (but am not 100% certain) that the minimum range is given with a 32-bit system in mind, while also letting the compiler use a couple of bits from the underlying 32-bit value for its own internal purposes like easily distinguishing numbers from pointers. (Something that I know Python and OCaml, at the very least, do.) GHC does not need to do this, so it exposes the full 32 or 64 bits as appropriate for its architecture.

Guadalupeguadeloupe answered 13/11, 2014 at 22:38 Comment(4)
Thanks for the very descriptive answer :) I'll follow your recommendation and stick to ghci while learning HaskellAirstrip
@SzymonStepniak: Cool. If you run into any more confusing inconsistencies, feel free to ask here.Guadalupeguadeloupe
I will do that, definitely. Thanks once again!Airstrip
In GHC INT is 64 bits even on 32 bit machines, but there's always Data.Int.Int32 if you need the smaller version (which for some reason is slower than 64 bit Ints even on my 32 bit machine)Zanthoxylum
D
4

Most likely you are on a 64 bit system where an Int has, well, 64 bits.

Try this:

Prelude> 2^62::Int
4611686018427387904
Prelude> 2^63::Int
-9223372036854775808
Daughterly answered 13/11, 2014 at 22:37 Comment(3)
"where an Int has, well, 64 bits." says whom?Emeryemesis
Int in GHC are implemented using machine integers.Daughterly
@JoachimBreitner The version of GHC in the Ubuntu package manager uses 64 bits for Int even on 32 bit machines (which for some reason is faster than using Data.Int.Int32)Zanthoxylum
L
4

Int is machine-sized. So on a 32-bit platform it'll overflow at 231.

$ ssh [email protected]
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

Note the Haskell Report really doesn't specify how big Int should be, exactly – as Tikhon Jelvis says, it's merely guaranteed to handle 229. But GHC certainly does use all machine integers, which is generally pretty optimal performance- and need-wise.

Laguna answered 13/11, 2014 at 22:39 Comment(1)
Thanks for the answer, now it looks reasonable :)Airstrip

© 2022 - 2024 — McMap. All rights reserved.