I have tried to create a function that determines if a list of lists has an empty list. However so far I don't seem to find any luck. So far I have tried using:
hasEmpty (x:xs) = if null x then True else False
However this only return true if the first list is empty.
I also tried:
hasEmpty (x:xs) = if null x || null xs then True else False
But it produces the same result.
I have also tried using any and elem but I couldn't get it working.
I am truly stumped on this. Any help would be much appreciated
2 Answers
The type of any is any :: Foldable t => (a -> Bool) -> t a -> Bool (use :t any) to get this.
There are two arguments:
- The first argument is a function which takes a value and returns a boolean, such as
null - The second argument is a foldable, such as a list
Hence we can simply use any null on a list.
lst = [[1],[],[3]]
lst2 = [[1],[3],[2]]
any null lst -- returns True
any null lst2 -- returns False
Comments
Recursion always has a base case. When you're dealing with lists, it's an empty list. If we try running an anyNull function on an empty list, it should return false.
anyNull :: [a] -> Bool
anyNull [] = False
But we also need to match the non-empty list and converge toward the base case. This is done by recursively calling the function on the list's tail. Fortunately pattern matching makes it easy to tell if the first element is an empty list, and then to handle the case where it is not empty.
anyNull :: [a] -> Bool
anyNull [] = False
anyNull ([]:_) = True
anyNull (_:xs) = anyNull xs
any? The solution withanyandnullis almost trivial.hasEmpty [[a]] = if any (==null) [[a]] then True else Falsebut it kept throwing an error. I now have realized it was an error on my part because I used any wrongly. My problem has been solved now thanks to Francis.