This function is incorrect and won't compile:
checkIsZero :: (Num a) => a -> String
checkIsZero a = if a == 0
then "Zero"
else "Not zero"
This doesn't work because of the comparison between a Num
and 0
in the expression a == 0
. Changing Num
to Integral
makes this a valid function.
What is this wicked sorcery that doesn't let me compare my numbers to 0
?!
It's indeed not possible to order complex numbers since they have no ordering defined. You can compare whether two complex numbers are equal or not, but not if one is larger than the other.
No, imaginary numbers are not greater than 0 or less than zero. They (or, more properly, the complex numbers that they're a subset of) are unordered, so the concepts of “greater than” and “less than” don't apply to them.
Zero can be classified as a whole number, natural number, real number, and non-negative integer. It cannot, however, be classified as a counting number, odd number, positive natural number, negative whole number, or complex number (though it can be part of a complex number equation.)
How to compare and order integers? Integers on the left side of 0 on the number line get smaller as we move from right to left, whereas integers on the right side of 0 get greater as we move from left to right. Therefore, to compare two integers, we can use greater than (>) or less than (<) symbols.
Num
requires instances to implement +
, *
, abs
, signum
, and fromInteger
. Note that ==
isn't on the list! It's instances of the Eq
typeclass that must implement ==
.
So, the Num
constraint is not sufficient - you need an Eq
constraint too. The following will compile.
checkIsZero :: (Eq a, Num a) => a -> String
checkIsZero a | a == 0 = "Zero"
| otherwise = "Not zero"
Integral
works because something which is an instance of Integral
must itself be an instance of Ord
, which in turn must be an instance of Eq
.
You can check all this stuff by using hoogle and digging into the source.
The reason for not requiring an Eq
instance to define a Num
instance is that it would rule out useful instances like
instance Num b => Num (a -> b) where
f + g = \x -> f x + g x
f - g = \x -> f x - g x
f * x = \x -> f x * g x
abs f = \x -> abs (f x)
signum f = \x -> signum (f x)
fromInteger = const . fromInteger
because you can't write an Eq
instance for a function.
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