Num class

Koen Claessen koen@cs.chalmers.se
Wed, 18 Oct 2000 12:57:56 +0200 (MET DST)


Hi all,

For years I have wondered why the Num class has the Eq class
and the Show class as super classes.

Because of this, I cannot make functions an instance of Num
(becuase they are not in Eq or Show). Or a datatype
respresenting an infinite amount of digits (because Eq would
not make any sense).

Now I have found out the reason!

However, it does not make me happy, it makes me even more
sad.

It is of the defaulting mechanism of course! The defaulting
mechanism works as follows: If there is an unresolved
overloading error on a type variable a, which has as an
*only* constraint (Num a), then we take a to be the suitable
default.

If Show were not a super class of Num, the following program
would generate an error:

  main = print 42

If Eq were not a super class, the following program would
not work:

  main = print (if 42 == 42 then "koe" else "apa")

These programs are all fixed by inserting Show and Eq as
super classes of Num. So that one does not even notice!

Until now.

I am interfacing to an external library that uses
double-precision floating points internally for all numbers.
This is to be as general as possible. However, I know that
when I put for example an Integer in, I get one out too.
Thus, I want to give a Haskell interface that can deal with
this by any numeric type. So I define a type class:

  class Num a => Number a where
    convertToDouble   :: a -> Double
    convertFromDouble :: Double -> a

(somehow the Haskell numerical hierarchy does not even let
me define general functions that do this! -- but that is
besides the point.)

  instance Number Int
  instance Number Integer
  instance Number Float
  instance Number Double
  ...

All my library functions now have the shape:

  libraryFunction :: Number a => ... a ...

Where as actually:

  primLibraryFunction :: ... Double ...

And now the bad thing... When I use "libraryFunction" on a
numeric constant, such as 42, I get the error:

  ERROR "library.hs" (line 8): Unresolved overloading
  *** Binding             : main
  *** Outstanding context : Number b

This is really annoying, and it is not clear why the default
mechanism works this way.

So here are my questions. Why does the default mechanism
have this restriction? I know that the default mechanism is
already broken (some desirable properties are destroyed) --
what properties will be broken by lifting this restriction?

/Koen.

--
Koen Claessen         http://www.cs.chalmers.se/~koen     
phone:+46-31-772 5424      mailto:koen@cs.chalmers.se
-----------------------------------------------------
Chalmers University of Technology, Gothenburg, Sweden