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?
CodePudding user response:
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
or 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)