5
votes

I am trying to understand the numeric type class hierarchy in Haskell. The basic numeric type is

class Num a where
...

As a side note, according to some of my sources (slides), it should actually be

class Eq a => Num a where
...

but I cannot find this in the Prelude.

Now, I am interested in the Real type class

class (Num a, Ord a) => Real a where
  -- the rational equivalent of its real argument with full precision
  toRational :: a -> Rational

I guess that Real refers to the fact that types that are instances of Real are not complex. But my understanding of a Real number from Mathematics is that it can be Rational and Irrational, so there is no equivalent of toRational for all of them. Of course, irrational numbers can't be used in computers anyways...

Thanks!

2
Num requiring Eq is in the Haskell report (the specification), but it's not included in GHC because it's a seriously annoying requirement. Num is generally regarded as one of the cruftier classes in Haskell: purescript's equivalent is a good example of what a redesign might look like. - oisdk
The change of Num no longer requiring Eq appears to have been made in the GHC 7.4 release: downloads.haskell.org/~ghc/7.4.1/docs/html/users_guide/… - Dominique Devriese
You say "irrational numbers can't be used in computers"; I say huh? what? - Daniel Wagner
Non-computable numbers can’t (really) be used by computers. Not all irrational numbers are non-computable though. A lot of the irrational numbers you come across in practical applications (like pi and e) are computable. - David Young

2 Answers

8
votes

Yes, the name Real is a rather misleading name for the class of types that can be converted to a rational.

Indeed, we have instances like Real Integer, Real IntPtr, Real CBool which can be very surprising.

The standard numeric classes are generally regarded as being a bit weird, both in their names and in their overall design.

4
votes

In general, Haskell's number classes are a bit of a mess. They're defined in a way that makes it convenient and easy to use the basic number types like Int, Integer, Double, etc. But when you start wanting more advanced kinds of numbers... they don't always make a lot of sense.


Regarding Num: This is interesting. Both the Haskell '98 and Haskell 2010 Report demand that

class (Eq a, Show a) => Num a

If you look at the documentation for base-4.0.0.0, you find this is the case:

http://hackage.haskell.org/package/base-4.0.0.0/docs/Prelude.html#7

However, at some point the base package was changed such that Num now has no superclasses (contradicting the Report). So your slides aren't wrong; it used to be defined that way, but it got changed at some point. If you dig far enough, there's probably a ticket or a wiki page about this.


Regarding Real... yes, the name is rather misleading. I'm also not really sure why it's different than RealFrac, which is also about conversions from a number to various ratios or integers.


If this kind of thing interests you, there are various "alternative Prelude" libraries out there (e.g., "classy Prelude", "numeric Prelude") which replace the standard Prelude with something hopefully a little bit more sensible. It turns out it's surprisingly hard to do this really well — which is why the official spec hasn't really changed much. Nobody has suggested anything conclusively better.