What is the difference is between the Floating
and Fractional
classes in Haskell?
The definitions of Fractional
and Floating
can be found in the documentation of the Prelude:
class Num a => Fractional a where (/) :: a -> a -> a recip :: a -> a fromRational :: Rational -> a
Fractional numbers, supporting real division.
[...]
class Fractional a => Floating a where pi :: a exp :: a -> a log :: a -> a sqrt :: a -> a (**) :: a -> a -> a logBase :: a -> a -> a sin :: a -> a cos :: a -> a tan :: a -> a asin :: a -> a acos :: a -> a atan :: a -> a sinh :: a -> a cosh :: a -> a tanh :: a -> a asinh :: a -> a acosh :: a -> a atanh :: a -> a
Trigonometric and hyperbolic functions and related functions.
[...]
So to translate that into English: A Fractional
is any kind of number for which I can define a division:
(/) :: Fractional a => a -> a -> a
That can for instance be the case for floating point numbers, but also for fractions (where a fraction has a numerator and denominator). This is not the case for Int
because if dividing an Int
by an Int
does not always produce an Int
(well technically floating point division on a computer is not exact, but that is another story).
A subset of Fractional
numbers are Floating
numbers where trigonometric are defined. It is for instance impossible that the sin
of a fraction always produces a fraction: a sin
is defined as an sum over an infinite sequence. Only for a very limited number of cases (like sin 0
) it holds. Basically the only numbers on a computer for which trigonometric are defined (approximatively) are floating point numbers.
Very roughly:
Fractional
is the class of types that can represent (exactly or at least in a decent approximation) any rational number. It may ad lib also be able to represent other numbers, but that's not important.
In other terms, it's just the class of number types that have a division operation; since it's a subclass ofNum
it follows from this that the types must contain the rational numbers.Floating
is the class of number types that are closed under limits in the Cauchy sense, i.e. complete spaces. This is necessary to do any sort of calculus. The methods of theFloating
class are functions that are mathematically defined as limits, namely infinite sums (which are the limits of the sequence of partial sums of taylor series).
Since you can define the real numbers as limits of sequences of rational numbers and because againFloating
is a subclass ofFractional
, anyFloating
type is able to represent (again, at least to a decent approximation) any real number.
A good way to visualise the difference is through topology: Floating
types are connected spaces, i.e. they form a continuum. What this means for floating point numbers is: every value is understood as a whole interval of real numbers (because floating-point always has some uncertainty). When you lay these intervals side by side, you tile the entire real numbers (at least to ±10300) without gaps.
By contrast, some Fractional
types are not connected. In particular, Rational
can exactly represent all its (rational-number) values, so each value is just an “infinitely small point”. You can never cover the entire real line with such points, and you can not compute functions like sin
or log
since the result of these functions is usually a non-rational real number.
It's worth pondering a bit what this “decent approximation” means. The Haskell standard doesn't define this. This story about every floating point number representing a whole interval of real numbers captures it quite well IMO. More generally, we might say: Num
/Fractional
/Floating
are the classes of types that represent equivalance classes of integer/rational/real numbers. In fact, these classes need not even be “small” intervals: in particular the finite types like Word32
or the standard Int
can be understood in a modular arithmetic sense, manifesting in results like (2^70 :: Int) == 0
, i.e. the equivalence classes are then numbers spaces by a multiple of 264.
In cases like Integer
or Rational
, the equivalence classes actually contain only a single element, i.e. the numbers are represented exactly. For real numbers, this is actually also possible, but much more tricky, it's called exact real arithmetic. There are libraries such as aern that do this.
Fractional
types are not connected" since the set of Floating
types is a subset of Fractional
types (since class Fractional a => Floating a
)? It's like saying "things that carry DNA/RNA are living" and forgetting about viruses (that have RNA but no metabolism). –
Holyhead Fractional
types are not connected, and gave Rational
as an example. –
Whyalla The definitions of Fractional
and Floating
can be found in the documentation of the Prelude:
class Num a => Fractional a where (/) :: a -> a -> a recip :: a -> a fromRational :: Rational -> a
Fractional numbers, supporting real division.
[...]
class Fractional a => Floating a where pi :: a exp :: a -> a log :: a -> a sqrt :: a -> a (**) :: a -> a -> a logBase :: a -> a -> a sin :: a -> a cos :: a -> a tan :: a -> a asin :: a -> a acos :: a -> a atan :: a -> a sinh :: a -> a cosh :: a -> a tanh :: a -> a asinh :: a -> a acosh :: a -> a atanh :: a -> a
Trigonometric and hyperbolic functions and related functions.
[...]
So to translate that into English: A Fractional
is any kind of number for which I can define a division:
(/) :: Fractional a => a -> a -> a
That can for instance be the case for floating point numbers, but also for fractions (where a fraction has a numerator and denominator). This is not the case for Int
because if dividing an Int
by an Int
does not always produce an Int
(well technically floating point division on a computer is not exact, but that is another story).
A subset of Fractional
numbers are Floating
numbers where trigonometric are defined. It is for instance impossible that the sin
of a fraction always produces a fraction: a sin
is defined as an sum over an infinite sequence. Only for a very limited number of cases (like sin 0
) it holds. Basically the only numbers on a computer for which trigonometric are defined (approximatively) are floating point numbers.
© 2022 - 2024 — McMap. All rights reserved.