haskellmoduloparity

How can I fix my code to work for all of the tests?


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:


Solution

  • 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.