How to check if a list in Haskell satisfies certain parameters?

Viewed 76

I have a variable:

checkList :: Integral a => [a] -> Bool

and I want to check if the inputted list has 10 elements and whether the sum of the elements is divisible by 10 and if both of these are satisfied then return True else return False. I tried this:

checkList [] = False
checkList(x:xs)
   |(1+checkList xs) div 10 == 1 && (x+checkList xs) mod 10 == 0 = True
   |otherwise                                                   = False

but it didn't work and gave an error saying:

• Couldn't match expected type ‘(a0 -> a0 -> a0) -> t1 -> a1’
  with actual type ‘Bool’
• The function ‘1 + checksum xs’ is applied to two arguments,
  but its type ‘Bool’ has none
1 Answers

You are trying to do too much in the same function. You can for example check if the list has ten elements by pattern matching it with [_,_,_,_,_,_,_,_,_,_] as pattern. This pattern will fail for lists from the moment these have more than ten elements and thus will fail for infinite lists as well. Furthermore you can use the sum :: (Num a, Foldable f => f a -> a to determine the sum of the list and check if it is dividable by 10 by checking if that sum s modulo 10 is zero:

checkList :: Integral a => [a] -> Bool
checkList xs@[_,_,_,_,_,_,_,_,_,_] = …
checkList _ = False

where I leave determining if the sum is dividable by 10 as an exercise (the … part). xs points to the entire list.

You can also define a function lengthEq :: Int -> [a] -> Bool that should return True only if the length is equal to a given length or not, so something similar to:

lengthEq :: Int -> [a] -> Bool
lengthEq n _ | n < 0 = False
lengthEq n [] = n == 0
lengthEq n (x:xs) = lengthEq (n-1) xs

The lengthEq will avoid that we get stuck in an infinite loop for an infinite list.

Then we can use this with:

checkList :: Integral a => [a] -> Bool
checkList xs = lengthEq 10 xs && …
Related