Numbers
Numeric types and classes
There are several numeric types and classes in Haskell:
type instance of
Int Num Integral
Integer Num Integral
Float Num Fractional Floating RealFrac
Double Num Fractional Floating RealFrac
Rational Num Fractional
The class Num
is a superclass of Integral
.
The class Fractional
is a superclass of Floating
.
- Whereas
Int
is bounded,Integer
is unbounded (bounded by memory only). - A
Double
is usually of higher precision than aFloat
. - The datatype
Rational
is for fractions.
Operations on numbers
Most operations on numbers and even numeric literals are overloaded:
(+) :: (Num a) => a -> a -> a
(-) :: (Num a) => a -> a -> a
(_) :: (Num a) => a -> a -> a
1 :: (Num a) => a -- overloaded literals
1.2 :: (Fractional a) => a -- overloaded literals
(/) :: (Fractional a) => a -> a -> a
mod :: (Integral a) => a -> a -> a
div :: (Integral a) => a -> a -> a
sin :: (Floating a) => a -> a
log :: (Floating a) => a -> a
No automatic coercion
We can use overloaded functions at different types:
3 * 4
3.2 * 4.5
But there is no implicit coercion:
3.2 * (5 `div` 2) -- type error
3.2 * fromIntegral (5 `div` 2)
Question
Why is 3.2 * 2
ok, but not 3.2 * (5 `div` 2)?
Because 2 :: (Num a) => a
, but (5`div`2) :: (Integral a) => a.
Converting between numeric types
From an integral type to another:
fromIntegral :: (Integral a, Num b) => a -> b
From a fractional type to an integral:
round :: (RealFrac a, Integral b) => a -> b
floor :: (RealFrac a, Integral b) => a -> b
ceiling :: (RealFrac a, Integral b) => a -> b
Here, round
rounds to the nearest even number.