Reputation: 117
I am trying to write a function using recursion eval :: Int -> Bool
that returns true if given a list where every odd number is greater than ten. For example:
eval [] == True
eval [1] == False
eval [2] == True
eval [1, 11, 21] == False
eval [2, 12, 22] == True
eval [21, 11] == True
I have to use recursion to do it, and I have got a base code:
eval :: [Int] -> Bool
eval [] = True
eval (x:xs) | mod x 2/= 0 && x > 10 = True
| otherwise = eval xs
The code runs, but it does not work for lists with an odd number greater than 10 as the first input, as it takes the first value of the list as the standard. I think that sorting the list in ascending order first, then performing the recursion would work, is that correct and if so how do I go about implementing it?
Upvotes: 1
Views: 491
Reputation: 476567
You should not return True
if mod x 2 /= 0 && x > 10
. At that point we still have to look for the rest of the numbers.
We thus can recurse on the tail only if the item is even or the item is greater than 10. Indeed, if an item is even then it is sufficient to continue, if it is not, we need to validate that that number is greater than 10.
So the eval
function thus works with:
eval :: [Int] -> Bool
eval [] = True
eval (x:xs) | even x || x > 10 = eval xs
| otherwise = False
We can simplify this with:
eval :: [Int] -> Bool
eval [] = True
eval (x:xs) = (even x || x > 10) && eval xs
We can also implement functions without the use of recursion, for example with a foldr
pattern:
eval :: (Foldable f, Integral a) => f a -> Bool
eval = foldr (\x -> ((even x || x > 10) &&)) True
or work with all :: Foldable f => (a -> Bool) -> f a -> Bool
:
eval :: (Foldable f, Integral a) => f a -> Bool
eval = all (\x -> even x || x > 10)
Upvotes: 3
Reputation: 654
You can pretty much just write down the problem specification:
f :: [Int] -> Bool
f = all (> 10) . filter odd
-- (And because you are supposed to write your own recursion)
where all p (x : xs) = p x && all p xs
all p [] = True
Upvotes: 1