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!
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With