2014-11-13 5 views
6

Sto leggendo Programming in Haskell libro e testare esempi forniti in GHCi interprete. Risulta che c'è una differenza nel comportamento del tipo Int nell'interprete GHCi e Hugs. Secondo il capitolo 3 della "Programmazione in Haskel", lo 2^31 :: Int dovrebbe andare al di fuori del range del tipo Int. Nel frattempo, in GHCi interprete ottengo:Perché il tipo Int 2^31 non supera l'intervallo in GHCi?

Prelude> 2^31 :: Int 
2147483648 

mentre in Abbracci si comporta proprio come il libro dice:

Hugs> 2^31 :: Int 
-2147483648 

In GHCi ho anche possibile controllare se il risultato è tipo di Int

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

Qual è la fonte della differenza descritto? Devo eseguire gli esempi dal libro in Hugs o usare GHCi che sembra essere la scelta raccomandata per l'apprendimento di Haskell? Sarò grato per il tuo aiuto.

+3

si dovrebbe solo disinstallare hugs – alternative

+0

@alternative: Penso che il download degli abbracci dovrebbe essere rimosso! O magari spostati in un luogo oscuro e protetti da una sorta di CAPTCHA specifico Haskell che necessita di una conoscenza dettagliata della differenza tra Haskell98 e Haskell2010 per rispondere ... – yatima2975

risposta

20

Un Int in Haskell deve sostenere almeno una serie di [-2^29 .. 2^29-1], ma può anche essere più grande. La dimensione esatta dipenderà sia dal compilatore che usi che dall'architettura in cui ti trovi. (Puoi leggere ulteriori informazioni a riguardo nello 2010 Haskell Report, lo standard più recente per il linguaggio Haskell.)

Con GHC su una macchina a 64 bit, avrai un intervallo di [-2^63..2^63 - 1]. Ma anche su una macchina a 32 bit, credo che la gamma di GHC ti consenta di essere un po 'più grande del minimo (presumibilmente [-2^31..2^31 - 1]).

È possibile verificare il limite attuale sono con maxBound e minBound:

> maxBound :: Int 
9223372036854775807 

Le differenze tra le implementazioni venire perché la definizione del linguaggio esplicitamente permette loro di attuare questi tipi in modo diverso. Personalmente, continuerei a usare GHCi solo tenendo questo a mente, perché GHC è di gran lunga il compilatore più probabile che userai. Se ti imbatti in più incongruenze, puoi cercarle nello standard o chiedere a qualcuno (proprio come qui!); pensala come un'esperienza di apprendimento;).

Lo standard è flessibile a questo proposito per consentire diversi compilatori e architetture di ottimizzare il codice diverso. Presumo (ma non sono sicuro al 100%) che l'intervallo minimo sia dato con un sistema a 32 bit in mente, lasciando anche che il compilatore usi un paio di bit dal valore di 32 bit sottostante per i propri scopi interni come distinguere facilmente numeri da puntatori. (Qualcosa che conosco, come minimo, Python e OCaml.) GHC non ha bisogno di fare questo, quindi espone i 32 o 64 bit a seconda della sua architettura.

+0

Grazie per la risposta molto descrittiva :) Seguirò la tua raccomandazione e seguirò 'ghci' mentre sto imparando Haskell –

+3

@SzymonStepniak: Cool. Se incontri incongruenze più confuse, sentiti libero di chiedere qui. –

+0

Lo farò, sicuramente. Grazie ancora! –

4

Molto probabilmente siete su un sistema a 64 bit in cui un Int ha, così, 64 bit.

Prova questo:

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

Corretto, è una CPU a 64 bit. Grazie per averlo indicato :) –

+0

"dove un Int ha, beh, 64 bit." dice chi? – newacct

+0

'Int' in GHC sono implementati usando numeri interi macchina. –

4

Int ha una dimensione di macchina. Così su una piattaforma a 32 bit che sarà traboccare al 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 

nota il Rapporto Haskell in realtà non specifica quanto grande Int dovrebbe essere, esattamente come dice – Tikhon Jelvis, è semplicemente garantito per gestire 2 . Tuttavia, GHC utilizza certamente tutti i numeri interi delle macchine, il che è in genere un ottimo livello di prestazioni e di necessità.

+0

Grazie per la risposta, ora sembra ragionevole :) –