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 Integrals 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 Floats, Strings, Chars, 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.

Tags:

Haskell