Deprecating fromIntegral

Henning Thielemann lemming at
Thu Sep 21 13:21:37 UTC 2017

On Thu, 21 Sep 2017, Niklas Hamb├╝chen wrote:

> It is a bit funny how we argue that Haskell is good for high assurance
> programming, and we build all sorts of fancy constructs to eliminate
> more run-time errors, when in fact we do worse than C in detecting
> errors in the most basic types a computer can use, such as converting
> between 64-bit and 32-bit integers.

That's all very true! Other safety oriented languages like Modula-3 at 
least perform a runtime check on integer conversion.

However, I'd like to see practical solutions first before adding 

fromInteger will always be partial when converting to a fixed width 
integer. fromInteger is used for converting number literals to the wanted 
type. Thus every number literal will issue a warning and I cannot see how 
to circumvent this.

Another problem I see is that integralUpsize and integralDownsize are not 
Haskell 98 and multi-parameter type classes are not really satisfying here 
because you have to define n^2 instances for n types. A convenient 
conversion function would certainly need even more advanced types, e.g. 
type-level comparison of bit widths.

If we have fixed fromIntegral then the next natural question would arise: 
How to protect arithmetic operations plus, minus, times against overflow? 
Aren't overflows as dangerous as losing bits on integer conversion? Is 
there a solution that works both for conversion and arithmetics?

For now the least invasive solution would be to provide a partial integer 
conversion function.

> So I propose that we add a deprecation pragma to `fromIntegral`
> (however, keeping it forever, like Java does, as there's no benefit to
> removing it, we just want that people use safer functions over time),
> and instead provide a `safeFromIntegral` that can only widen ranges, and
> one or more `unsafeFromIntegral` or appropriately named functions that
> can error, wrap, return Maybe, or have whatever desired behaviour when
> the input value doesn't fit into the output type.

As always, I object to use the terms 'safe' and 'unsafe' when actually 
'total' and 'partial' are meant. LLVM uses 'ext' and 'trunc'. I'd prefer 
names along these lines.

More information about the Libraries mailing list