[Haskell-cafe] ANN: convertible (first release)
wren ng thornton
wren at freegeek.org
Wed Jan 28 17:28:41 EST 2009
John Goerzen wrote:
> wren ng thornton wrote:
> > I once again point out that realToFrac is *wrong* for converting from
> > Float or Double.
> >
> > > realToFrac (1/0::Float) ::Double
> > 3.402823669209385e38
>
> Yes, I understand what you are saying and agree with you. But there
> is nothing better in the standard library, and I did not feel it was
> worth adding another dependency to the package simply for the sake of
> this sort of thing. People that need it can get it for themselves and
> write their own instance of Convertible if they wish.
Then add a wrapper that calls Prelude.isNaN and Prelude.isInfinite in
order to guard against these values just like you do for conversion from
unbounded types to bounded types.
Avoiding a trivial dependency is no excuse for avoiding correctness.
> > These exceptional values are not uncommon and should be dealt with
> > correctly. The code to do this is already written in
> > logfloat:Data.Number.Transfinite[1], simply use the realToFrac method of
> > the RealToFrac class instead of the Prelude's version which is broken.
>
> I wonder if you would consider submitting a patch to base? It seems
> that this is a sore problem there, and ideally should be dealt with
> properly in base.
As Bertram Felgenhauer says, it's not as easy as fixing base; the
problem is an error in the Haskell98 specification. The Float and Double
types contain exceptional values which cannot be represented in Rational
(by definition). The only Haskell98 solution is to raise an error when
attempting to convert those values into Rational, which isn't much of an
improvement.
At some point I may propose the logfloat solution for Haskell Prime.
MPTCs have already been accepted, but the logfloat solution does
necessitate additional non-insignificant changes. For example there
should be a class for partially ordered types[1][2]. To reduce code
bloat a PartialOrd instance should be available whenever an Ord instance
is; which means opening the whole can of worms about changing the
numeric class hierarchy and changes to the type-class mechanism in order
to simplify defining all those different instances. So far I've held off
on proposing the solution because I haven't worked out the best way to
resolve these issues with minimal changes.
[1] The Ord instance for Float and Double is also wrong, since NaN means
there's no total ordering (and the existence of NaN is necessitated by
the existence of Infinity). In addition to the fact that partial
orderings are more common than total orderings, this means we should
have a partial ordering class anyways.
[2] There's also the issue of what type the partial and total comparison
functions should return. Logfloat uses Maybe Ordering to make use of the
various helper functions and type classes defined on those types, but
for performance reasons we would much rather prefer a flat type. It's
inelegant to have both Ordering and PartialOrdering types; and it's
hackish to just have PartialOrdering and have Ord ensure that the
NotComparable value is never generated.
--
Live well,
~wren
More information about the Haskell-Cafe
mailing list