Skip to content

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:

GHCi
>>> :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:

GHCi
>>> 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:

GHCi
>>> 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.