[Haskell-cafe] Type class hierarchy for floats (Was: map (-2) [1..5])

Henning Thielemann lemming at henning-thielemann.de
Mon Sep 11 10:51:48 EDT 2006

On Sat, 9 Sep 2006, Jón Fairbairn wrote:

> Aaron Denney <wnoise at ofb.net> writes:
> > On 2006-09-08, Jón Fairbairn <jon.fairbairn at cl.cam.ac.uk> wrote:
> > > Why shouldn't Naturals be more primitive than Integers?
> > 
> > Certainly they're more primitive.  Too primitive to have reasonable
> > algebraic properties.
> Hmph. Naturals obey (a+b)+c == a+(b+c), which is a nice and
> reasonable algebraic property that Float and Double don't
> obey. In fact Float and Double have lots of /un/reasonable
> algebraic properties, but we still have them in the
> language.  (I think they should be turfed out into a
> numerical library).

Since floats are so different, maybe we should provide a different type
hierarchy for them. Say

class Additive a where
   (+) :: a -> a -> a

class Additive a => Ring a where
   (*) :: a -> a -> a

class ApproximateRing a where
   (+~) :: a -> a -> a
   (*~) :: a -> a -> a

instance ApproximateRing Float
instance ApproximateRing Rational
instance Ring Rational

Approximating numeric class instances do not satisfy the algebraically
interesting laws, whereas instances of exact numeric class satisfy them.
That is, floating point and fixed point numbers can only be instances of
Approximate* classes and exact representations of mathematical objects
like integers, rationals, complex numbers, polynomials can be instances of
both exact and approximating numeric classes. However, e.g. the integers
as presented in the computer still constitute no ring, because the domain
is not closed.  E.g. a power with sufficient high exponent lets any
Haskell program run out of memory. Having different type hierarchies for
approximating and exact numbers may be inconvenient at the first glance,
because you have to implement say polynomial and matrix multiplication for
both kinds of type classes, but they can share code and they can adapt to
subtle differences.  E.g. a fast determinant algorithm for a matrix over
rings is totally different from a fast and numerically stable determinant
computation of float matrices.

More information about the Haskell-Cafe mailing list