
On Wed, Apr 09, 2003 at 04:21:34PM +0100, Alastair Reid wrote:
Ross Paterson
writes: Under Hugs, fromInteger (and thus fromIntegral) throws an exception if the argument is outside the representable range of values, while GHC just truncates.
I would say that GHC implements a performance optimization by dropping the check and that the behaviour outside the range of Int should be treated as undefined (which is not the same as 'implementation defined').
OK, consider conversions between Int<n> and Word<n>, where the documented behaviour (in Data.Int and Data.Word) is to preserve representation. If you concede that, then since this conversion goes through fromInteger, it would need to accept at least the range -2^(n-1)..2^n-1 for both types. Stopping there would be hard to explain, but I suppose it would achieve your aim of unpredictable harassment of people who use these types nonportably.
And some of the libraries rely on the GHC behaviour.
I would say that such code is broken since it relies on a non-portable feature.
The example I came across was System.Posix.IO.fdRead, where a read call is declared as returning CSize (= Word32), and put inside throwErrnoIfMinus1Retry, resulting in fromInteger (-1) :: Word32. I guess the neat thing would need a Haskell equivalent of Posix's ssize_t type, but the version there is legal according to the documented behaviour.