Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong function type declaration

Tags:

haskell

I have the following function that sholud return only odd numbers from the List

oddsOnly :: Integral a => [a] -> [a]
oddsOnly [] = []
oddsOnly (x:xs)
 |odd x = x : oddsOnly xs
 |otherwise = oddsOnly xs

My question is about the aim of using

Integral a =>

Actually it is not posssible to implement such function with such type declaration

oddsOnly :: [a] -> [a]

As far as I know even and odd functions are in standart Prelude library so why simplified daclaration does not work?

Thanks in advance

like image 758
Fedo Avatar asked May 16 '20 14:05

Fedo


2 Answers

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.

like image 180
ForceBru Avatar answered Sep 25 '22 00:09

ForceBru


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
like image 20
Willem Van Onsem Avatar answered Sep 23 '22 00:09

Willem Van Onsem