2014-10-26 16 views
25

Le versioni recenti di ghc ti avviseranno se un valore letterale intero è esterno all'intervallo di un determinato tipo. Ad esempio:Esiste un tipo intero senza segno che avviserà in caso di valori letterali negativi?

$ ghci 
>>> let x = 330492039485 :: Data.Word.Word8 
<interactive>:2:9: Warning: 
    Literal 330492039485 is out of the GHC.Word.Word8 range 0..255 

Tuttavia, ghc non avvisa circa valori numerici negativi per Data.Word tipi. Invece, underflow (intenzionalmente, in base alla documentazione):

>>> let x = -1 :: Data.Word.Word8 
>>> x 
255 

Ci sono tipi che si mettono in guardia letterali negativi o c'è un modo posso creare il mio tipo personalizzato che fa mettere in guardia?

+0

Guardando all'origine per Data.Word, sembra che gli avvertimenti siano integrati nel compilatore. C'è un modulo 'Panic' nel pacchetto nascosto ghc che sembra possa emettere degli avvertimenti, ma non sembra una soluzione ottimale. – bheklilr

+0

Recentemente ho voluto uno o due sottotipi di numero intero, vale a dire naturale e positivo (e Positivo è facoltativo per me), che idealmente utilizzare la famiglia di funzioni 'mpn_' in GMP per la loro implementazione. Abbiamo 'Nat' a livello di testo ma niente al livello di valore, e questo mi sembra strano, quindi terrò d'occhio le risposte! – yatima2975

+3

Come per la tua domanda, c'è una distinzione da fare: 'Word8' rappresenta gli interi modulo 256 (nel qual caso il fatto che' -1 == 255' è perfettamente ragionevole), o è inteso a rappresentare l'insieme ' {0, ..., 255} '(nel qual caso' -1 == 255' dovrebbe essere mal digitato)? Si lega anche al disordinato design 'Num'; '(-)', 'negate' e' fromInteger' non dovrebbero essere lì (figuriamoci 'abs' e' signum'!), ma questa è una lattina diversa di worm ... – yatima2975

risposta

37

Per impostazione predefinita, un valore letterale come -1 è impostato su negate (fromInteger 1). Esiste tuttavia un'estensione di lingua NegativeLiterals che lo induce a desugar come fromInteger (-1). Se si abilita che fare ottenere un avvertimento:

Prelude> :m +Data.Word 
Prelude Data.Word> :set -W 
Prelude Data.Word> :set -XNegativeLiterals 
Prelude Data.Word> -1 :: Word 

<interactive>:74:1: Warning: 
    Literal -1 is out of the Word range 0..18446744073709551615 
18446744073709551615 
Prelude Data.Word> 

alternativa, è possibile creare il proprio tipo che ha ridefinito negate, ma poi si sarebbe presumibilmente ottenere solo un errore di runtime.

+0

Grazie! Questo e 'esattamente quello che stavo cercando –

Problemi correlati