Wrong function type declaration
why simplified daclaration does not work?
Because you can't tell if a string is odd or not. Or if a float is odd or not. In general, it's not possible to tell if a value of any type a
is odd or not because the notion of being odd may not be defined for this type.
It is defined, however, for Integral
types, so you must specify that a
is Integral
.
In terms of Haskell, odd
works on Integral
s only:
Prelude> :t odd
odd :: Integral a => a -> Bool
Thus, you must pass it a value of a type that is Integral
.
The signature of odd
and even
is odd :: Integral a => a -> Bool
and even :: Integral a => a -> Bool
respectively. So these contain an Integral a
type constraint [Haskell-wiki].
A type constraint has nothing to do from where it is defined. It specifies that the function only is defined for a subset of types. Only for types that are members of the Integral
typeclass, you can use the function. Integral types are types like that specify a subset of ℤ, so Int
, Int64
, Word8
, Integer
, … Types. odd
and even
do not make much sense over Float
s, String
s, Char
s, etc. What would that mean?
By thus specifying the Integral a =>
type constraint, you specify that this function can only work with integer-like items.
Note that you can use filter :: (a -> Bool) -> [a] -> [a]
here to retain only odd numbers:
oddsOnly :: Integral a => [a] -> [a]
oddsOnly = filter odd
Let’s look at the type signature of odd
: odd :: Integral a => a -> Bool
. So to use odd
with a parameter, that parameter needs to be Integral
. This makes sense intuitively: as @ForceBru said in another answer, you can’t tell whether e.g. a float such as 1.5
or a string such as "hello"
is odd, as the notion of oddness is only defined for integral values.