Other Number Types
The Haskell standard library offers a number of additional number types that you will work with less frequently, but which may nevertheless come in handy:
Rational Numbers
First, there's a rational number type Rational
:
>>> :info Rational
type Rational :: *
type Rational = GHC.Real.Ratio Integer
-- Defined in ‘GHC.Real’
As this tells us Rational
is actually an alias for Ratio Integer
. Ratio
is
a more general rational number type whose type parameter specifies which type is
used to represent the rational number's numerator and denominator. Rational
uses unbounded-width integers, Integer
. Data.Ratio Int
may be more efficient
to work with, but you'll have to worry about the possibility of integer overflow
then.
Rational numbers support the standard arithmetic and comparison operators:
>>> x = 4 / 3 :: Rational
>>> y = 10 / 8 :: Rational
>>> x
4 % 3
>>> y
5 % 4
>>> x * y
5 % 3
>>> x < y
False
You have to get used to the weird way that Haskell uses to write rational
numbers: using %
to separate numerator from denominator. Beyond that, they
work as expected. The implementation of operations on rational numbers
reduces each number to the representation with the smallest possible
denominator: We defined \(y = \frac{10}{8}\). Since \(\frac{10}{8} = \frac{5}{4}\),
GHCi prints 5 % 4
when we ask it for y
's value.
I tend to use rational numbers when I need to work with fractional values and I cannot live with the rounding errors that arise when performing floating point arithmetic. The implementation of geometric algorithms is a great example where even the smallest rounding errors can make these algorithms compute complete nonsense.
Complex Numbers
Complex numbers are supported via the Data.Complex
module:
>>> import Data.Complex
>>> sqrt ((-1) :+ 0)
0.0 :+ 1.0
So, we write complex numbers by using (:+)
to separate the real part from the
imaginary part. Surely not the most intuitive notation, but at least it's
succinct, and Haskell programmers tend to value succinctness.
Here, I took the square root of –1, which, as expected, is \(i\).
If you're interested in complex number support in Haskell, then look up
Data.Complex
on Hoogle. We won't be working with them in this course, but I
would have been remiss not to mention them.
That's it for number types for now. Let's look at Booleans next.