NegativeLiterals / Lexical negation prevent (ab)using "negative" zero.
With NegativeLiterals
and LexicalNegation
, -0
is desugared as fromInteger (-0 :: Integer) = fromInteger (0 :: Integer)
.
That prevents some tricks possible in Haskell98.
One concrete example is e.g. SAT literals, with variables usually being natural numbers: 0, 1, 2, 3, ... And positive literals being 0, 1, 2, 3 and negative literals -0 -1 -2 -3 -4. DIMACS format explicitly starts variables from 1 instead of 0 so negate
can be used to negate literals. But e.g. minisat implementation uses one bit of the unsigned word to indicate literal positivity (negLit lit = complementBit lit 0
, litToVar lit = shiftR lit 1
; this encoding has another benefits).
My point is that: Negativeliterals
and LexicalNegation
can change the meaning of program.
I think the information should be at least reflected in the docs. People who (ab)use Num
for (mostly) overloaded numeral literals should be warned (Num
doesn't have a law that negate . fromIntegral = fromIntegral . negate
!). Also IMO this subtlety is on the way of including either extension in GHC20xx language versions. fromInteger
in Num
is not a great design.