Decide whether the items in the list all give the same remainder divided by two.
My code is working when the mod is 1, but it is not working when the mod is 0. What do I have to add to work? An if - else statement or something else?
sameParity :: [Int] -> Bool
sameParity [] = True
sameParity (x: xs)
| x `mod` 2 == 1 = sameParity xs
| x `mod` 2 == 0 = sameParity xs
| otherwise = False
Examples:
Each of the following test cases must give a True:
sameParity [] == True
sameParity [1..10] == False
sameParity [1,3..10] == True
sameParity [2, 42, 0, 8] == True
sameParity (1: [2, 42, 0, 8]) == False
CodePudding user response:
At every step, you have to check if the parity of the rest of the elements is the same as all the previous elements. Problem is, at every step you no longer know all the previous elements. They're lost now.
So what you have to do is pass the parity of all previous elements into the next step as a parameter:
allHaveParity [] _ = True
allHaveParity (x:xs) prevItemsParity = (x `mod` 2 == prevItemsParity) && (allHaveParity xs prevItemsParity)
> allHaveParity [1,3] 1
True
> allHaveParity [2,4] 0
True
> allHaveParity [1,2] 1
False
But, of course, this is now mighty inconvenient, because now you have to pass the "expected" parity in, rather than just having the function figure it out.
But no fear! Just wrap this function in another, which would take the first item's parity and pass it down:
sameParity [] = True
sameParity (x:xs) = allHaveParity xs (x `mod` 2)
And now it can be easily observed that, once we have the first item's parity, we can use the existing all
function to check all the other items:
sameParity [] = True
sameParity (x:xs) =
let firstParity = x `mod` 2
in all (\a -> (a `mod` 2) == firstParity) xs
And throw away the allHaveParity
function. It was doing the same thing, but with explicit recursion.