[Haskell-cafe] instance Enum Double considered notentirelygreat?
donn at avvanta.com
Tue Sep 27 09:29:20 CEST 2011
Quoth Chris Smith <cdsmith at gmail.com>,
> So that's what this is about: do we think of Float as an approximate
> real number type, or as an exact type with specific values. If the
> latter, then "of course" you exclude the value that's larger than the
> upper range. If the former, then using comparison operators like '<'
> implies a proof obligation that the result of the computation remains
> stable (loosely speaking, the function continuous) at that boundary
> despite small rounding error in either direction. In that case,
> creating a language feature where, in the *normal* case of listing the
> last value you expect in the list, 0.3 (as an approximate real number)
> is excluded from this list just because of technicalities about the
> representation is an un-useful implementation, to say the least, and
> makes it far more difficult to satisfy that proof obligation.
It doesn't appear to me to be a technicality about the representation -
the value we're talking about excluding is not just represented as
greater than 0.3, it is greater than 0.3 when applied in computations.
For example you can subtract 0.3 and get a nonzero value (5.55e-17.)
Isn't the problem here with ranges really that they're computed in a
way that doesn't work for FP? I mean, when I specify [0.1,0.2..0.5],
I really do mean to include 0.5 among those values, as you surmise -
so I imply a computation that actually produces that value, i.e.,
0.5::Double. The disappointment with iterative addition is not that
its fifth value [should be] omitted because it's "technically" greater,
it's that range generation via iterative addition does not yield the
values I specified.
In other words, a range is a shorthand expression, where the correct
value is the one that would have resulted from evaluating the corresponding
list of constant expressions. If we don't know how to generate that
list correctly for Double, then I suppose range shouldn't be supported,
but I thinking I'm seeing hints that we may indeed know how to do this?
(I sure don't! though of course for a specific case it can be easy,
e.g., (map (/ 10.0) [1..5]).)
More information about the Haskell-Cafe