2014-11-13 2 views
6

Я читаю Programming in Haskell Книга и тестирование предоставлены примеры в интерпретаторе GHCi. Оказывается, существует разница в поведении типа Int в интерпретаторе GHCi и Hugs. Согласно главе 3 «Программирование в Haskel», 2^31 :: Int должен выйти за пределы диапазона Int. Между тем, в интерпретатором GHCi я получаю:Почему Int тип 2^31 не выходит за пределы диапазона в 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? Буду признателен за вашу помощь.

+3

вы должны просто удалить объятия – alternative

+0

@alternative: Я думаю, что скачать объятия нужно снести! Или, возможно, переместился в неясное место и защищен каким-то специальным CAPTCHA от Haskell, которому требуется подробное знание разницы между Haskell98 и Haskell2010, чтобы ответить ... – yatima2975

ответ

20

в Haskell Int должен поддерживать по крайней мере целый ряд [-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 бит, как это соответствует его архитектуре.

+0

Спасибо за очень описательный ответ :) Я буду следовать вашей рекомендации и придерживаться 'ghci', изучая Haskell –

+3

@SzymonStepniak: Cool. Если вы столкнетесь с более сложными несоответствиями, не стесняйтесь спрашивать здесь. –

+0

Я сделаю это, определенно. Еще раз спасибо! –

4

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

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

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

Правильно, это 64-битный процессор. Спасибо, что указали на это :) –

+0

«где Int имеет, ну, 64 бит». говорит кто? – newacct

+0

'Int' в GHC реализованы с использованием целых чисел. –

4

Int является машинным размером. Итак, на 32-битной платформе будет переполняться на 2 .

$ 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 
[email protected]:~$ 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, это просто гарантированно обрабатывать 2 . Но GHC, конечно же, использует все машинные целые числа, что, как правило, довольно оптимально для производительности и потребностей.

+0

Спасибо за ответ, теперь он выглядит разумным :) –