Break unnecessary dependencies between Haskell numeric classes
Motivation:
The Haskell numeric classes contain some interdependencies that look rather odd to a mathematician. For example, why do you have to be Show in order to be Num, and why do you have to be Enum in order to be Integral. These dependencies are not justified by mathematical considerations, and make it hard to represent some mathematical concepts in Haskell.
For example, consider the Gaussian integers - numbers of the form a+bi, where a and b are integers, and i is the square root of -1. (Complex Integer, if you like.) There is a division with remainder algorithm for the Gaussian integers, so that we would like to declare them as an instance of Integral, and define the quotRem function. However, to do this we would have to declare them as an instance of Enum - and this makes no sense - there is no natural way to define the Enum functions on the Gaussian integers.
For similar reasons, the dependency of Integral on Real is suspect - there is no natural way to define toRational on the Gaussian integers.
The dependency of RealFrac on Fractional is also unnecessary - what have floor, ceiling etc got to do with recip?
Note that breaking these dependencies will not break any existing code. At present, if I declare a type T to be a Num instance, I must also declare it to be an Eq instance and a Show instance. If the dependency is broken, that is, if
class (Eq a, Show a) => Num a
is replaced by
class Num a
then existing code will still work.
What will have changed is that it will now be possible to declare a type T to be a Num instance without also declaring it to be an Eq and a Show instance.
Proposal:
Conservative version:
Replace the existing Prelude class declarations with:
- class Eq a => Num a -- remove dependency on Show
- class Num a => Integral a -- replace dependency on Real, Enum by dependency on Num
- class Real a => RealFrac a -- remove dependency on Fractional
Radical version:
In addition to the above:
- Split abs and signum out from Num into a new
class Num a => Quantity a
(There are plenty of objects in mathematics for which the arithmetical operations +,-,* make sense, but the size and direction operations abs and signum do not - for example polynomials, matrices.)
- Amalgamate classes Real and RealFrac - Real no longer has any purpose as a distinct class. The new class should probably be called Real.
See also: NumericClasses.