
I don't mind doing this, but can someone first give a brief justification
about why it's a good idea, independent of the discussion that
has taken place on this list? I'd like to add such an explanation
to the code.
Simon
| -----Original Message-----
| From: qrczak@knm.org.pl [mailto:qrczak@knm.org.pl]
| Sent: 16 February 2001 17:42
| To: haskell-cafe@haskell.org
| Subject: Re: Primitive types and Prelude shenanigans
|
|
| Thu, 15 Feb 2001 20:56:20 -0800, William Lee Irwin III
|

Tue, 20 Feb 2001 08:33:46 -0800, Simon Peyton-Jones
I don't mind doing this, but can someone first give a brief justification about why it's a good idea, independent of the discussion that has taken place on this list?
Suppose we build an alternative Prelude with different numeric class hierarchy, and decide that types for natural numbers should not have 'negate' defined, as it's obviously meaningless for them. We can put 'fromInteger' in some class and 'negate' in its subclass, and make only the former instance for natural numbers. So -9 :: Natural should be a compile error. Negation is already an error for all expressions other than literals when negate has a wrong type for them; literals should not be an exception. Negated literals are still treated in a special way in patterns, but -9 in a pattern should expand to testing equality with negate (fromInteger 9), not fromInteger (-9), to catch types which intentionally don't have negate defined. -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK

On 20-Feb-2001, Simon Peyton-Jones
I don't mind doing this, but can someone first give a brief justification about why it's a good idea, independent of the discussion that has taken place on this list? I'd like to add such an explanation to the code.
How about "Because the Haskell 98 Report says so"? ;-)
It's a pity there's no Haskell 98 Rationale, like the Ada 95
Rationale... if there was, then the documentation in the ghc code
could just point at it.
----------
There is however one issue with this change that concerns me.
I'm wondering about what happens with the most negative Int.
E.g. assuming 32-bit Int (as in Hugs and ghc), what happens with
the following code?
minint :: Int
minint = -2147483648
I think the rules in the Haskell report mean that you need to write
that example as e.g.
minint :: Int
minint = -2147483647 - 1
ghc currently allows the original version, since it treats negative
literals directly, rather than in the manner specified in the Haskell report.
ghc also allows `(negate (fromInteger 2147483648)) :: Int', apparently
because ghc's `fromInteger' for Int just extracts the bottom bits (?),
so changing ghc to respect the Haskell report's treatment of negative
literals won't affect this code.
But the code does not work in Hugs, because Hugs follows the Haskell
report's treatment of negative literals, and the `fromInteger' in Hugs
does bounds checking -- Hugs throws an exception from `fromInteger'.
The documentation in the Haskell report does not say what
`fromInteger' should do for `Int', but the Hugs behaviour definitely
seems preferable, IMHO. However, this leads to the unfortunate
complication described above when writing a literal for the most
negative Int.
Of course using `minBound' is a much nicer way of finding out the
minumum integer, at least in hand-written code. But this issue might
be a potential pitfall for programs that automatically generate
Haskell code.
--
Fergus Henderson

Wed, 21 Feb 2001 12:55:37 +1100, Fergus Henderson
The documentation in the Haskell report does not say what `fromInteger' should do for `Int', but the Hugs behaviour definitely seems preferable, IMHO.
Sometimes yes. But for playing with Word8, Int8, CChar etc. it's sometimes needed to just cast bits without overflow checking, to convert between "signed bytes" and "unsigned bytes". -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK

On 21-Feb-2001, Marcin 'Qrczak' Kowalczyk
Wed, 21 Feb 2001 12:55:37 +1100, Fergus Henderson
pisze: The documentation in the Haskell report does not say what `fromInteger' should do for `Int', but the Hugs behaviour definitely seems preferable, IMHO.
Sometimes yes. But for playing with Word8, Int8, CChar etc. it's sometimes needed to just cast bits without overflow checking, to convert between "signed bytes" and "unsigned bytes".
Both are desirable in different situations. But if you want to ignore
overflow, you should have to say so explicitly. `fromInteger' is
implicitly applied to literals, and implicit truncation is dangerous,
so `fromInteger' should not truncate.
There should be a different function for conversions that silently
truncate. You can implement such a function yourself, of course,
e.g. as follows:
trunc :: (Bounded a, Integral a) => Integer -> a
trunc x = res
where min, max, size, modulus, result :: Integer
min = toInteger (minBound `asTypeOf` res)
max = toInteger (maxBound `asTypeOf` res)
size = max - min + 1
modulus = x `mod` size
result = if modulus > max then modulus - size else modulus
res = fromInteger result
But it is probably worth including something like this in the standard
library, perhaps as a type class method.
--
Fergus Henderson
participants (3)
-
Fergus Henderson
-
qrczak@knm.org.pl
-
Simon Peyton-Jones