Reputation: 407
I'm trying to write a Haskell function that checks if a list of integers is in order without using any of the already existing functions to order or check the order of the list. I have written the following code but I do not understand why it does not work. I get the error:
No instance for (Ord integer)
arising from a use of `<='
In the expression: x <= (head xs)
I don't understand what this means. Is there a different way that I should be writing this function? Here is my code so far.
isordered :: [integer] -> Bool
isordered [] = True
isordered (x:[]) = True
isordered (x:xs)|x <= (head xs) = isordered xs
|otherwise = False
Thanks in advance!!!
Upvotes: 1
Views: 1678
Reputation: 4496
Another way for doing it using guards:
isOrdered :: Ord a => [a] -> Bool
isOrdered (x:y:xs) | x<=y = isOrdered (y:xs)
| otherwise = False
isOrdered _ = True
Upvotes: 0
Reputation: 54574
What exactly counts as "already existing function"?
isordered xs = all (uncurry (<=)) $ zip xs (tail xs)
More low-level is
isordered (x:y:zs) = x <= y && isordered (y:zs)
isordered _ = True
Upvotes: 3
Reputation: 370112
In Haskell type names start with capital letters and type variables start with lower case letters. So if you write integer
, that's a type variable. So your type is the same as [a] -> Bool
, i.e. you take a list of anything and return a Bool. So since there's no restriction on what type of item might be in the list, you're not allowed to use <=
on it.
To fix this you can either just change it to Integer
, which is what you wanted, or add an Ord constraint like this: Ord a => [a] -> Bool
. The latter will make your function work with any type that implements the Ord
typeclass (which provides the comparison operators such as <=
).
Upvotes: 8