Почему Int type 2^31 не выходит за пределы диапазона в GHCi?

Я читаю программирование в Haskell книга и тестирование предоставили примеры в интерпретаторе GHCi. Оказывается, есть разница в Int введите поведение в интерпретаторе GHCi и Hugs. Согласно главе 3 "программирование в Хаскеле",2^31 :: Int должен выйти за пределы диапазона Int тип. Между тем, в переводчике GHCi я получаю:

Prelude> 2^31 :: Int
2147483648

в то время как в объятиях он ведет себя так же, как книга говорит:

Hugs> 2^31 :: Int
-2147483648

в GHCi я могу даже проверить, если результат типа Int

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

в чем источник описанной разницы? Должен ли я запускать примеры из книги в объятиях или использовать GHCi, который, похоже, рекомендуется для изучения Haskell? Я буду благодарен вам за помощь.

3 ответов


An Int в Haskell должен поддерживать по крайней мере ряд [-2^29 .. 2^29-1], но он также может быть больше. Точный размер будет зависеть как от используемого компилятора, так и от архитектуры. (Вы можете прочитать больше об этом в 2010 Haskell Report, последний стандарт для языка Haskell.)

С GHC на 64-битной машине у вас будет диапазон [-2^63..2^63 - 1]. Но даже на 32-битной машине я считаю, что диапазон GHC дает вам немного больше, чем строгий минимум (предположительно [-2^31..2^31 - 1]).

вы можете проверить, что фактическая граница с maxBound и minBound:

> maxBound :: Int
9223372036854775807

различия между реализациями возникают из-за определения языка явно позволяет им реализовывать эти типы по-разному. Лично я бы продолжал использовать GHCi просто имейте это в виду, потому что GHC является наиболее вероятным компилятором, который вы будете использовать. Если вы столкнетесь с большим несоответствия, вы можете либо посмотреть их в стандарте, либо спросить кого-то (как здесь!); думайте об этом как об учебном опыте ;).

стандарт является гибким в этом отношении, чтобы позволить различным компиляторам и архитектурам оптимизировать свой код по-разному. Я предполагаю (но не уверен на 100%), что минимальный диапазон задается с учетом 32-битной системы, а также позволяет компилятору использовать пару битов из базового 32-битного значения для своих собственных внутренних целей, таких как легко отличать числа от указателей. (Что-то, что я знаю Python и OCaml, по крайней мере, делают.) GHC не нужно делать это, поэтому он предоставляет полные 32 или 64 бита в соответствии с его архитектурой.


скорее всего, вы находитесь в 64-битной системе, где Int имеет, ну, 64 бита.

попробуйте это:

Prelude> 2^62::Int
4611686018427387904
Prelude> 2^63::Int
-9223372036854775808

Int - Это машина размера. Так что на 32-бит платформа переполнится в 231.

$ 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 должно быть, именно – как Тихон Jelvis говорит, это просто гарантированно ручки 229. Но GHC, безусловно, использует все машинные целые числа, что, как правило, довольно оптимальная производительность и необходимость.