Почему 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, безусловно, использует все машинные целые числа, что, как правило, довольно оптимальная производительность и необходимость.