I need to compare if all elements of a given list are unique. (For the record I am doing so for academic purposes.)
Here is what I have thus far:
allDifferent :: (Eq a) => [a] -> Bool
allDifferent list = case list of
[] -> True
(x:xs) -> if x `elem` xs then False else allDifferent xs
Which works wonderfully!
Now, when I try to do it like this...
allDifferent2 :: (Eq a) => [a] -> Bool
allDifferent2 list
| null list = True
| (head list) `elem` (tail list) || allDifferent2 (tail list) = False
| otherwise
It just doesn't work as intended. I get the following output from GHCi:
*Main> allDifferent2 [1..4]
False
*Main> allDifferent2 [1..5]
True
*Main> allDifferent2 [1..6]
False
*Main> allDifferent2 [1..7]
True
i.e. For every list with an even amount of elements it outputs False and for an odd amount of elements, True.
What am I missing? Would anyone care to shine some light?
if it is just about knowing if the list contains duplicates you can use the nub function in Data. List like so: hasDup l = nub l == l (nub removes all duplicates... so this will be true only if there are no duplicates in the list.)
elem :: element -> list -> Bool. Use elem if you want to check whether a given element exists within a list.
The sequence (n:ns) is a shorthand for head - tail. Quite literally, the first value, the head, is called n and the remained are the other, potentially plural, n s, which is why it is called ns . Haskell has pattern matching.
An alternative exploiting notElem
:
allDifferent :: (Eq a) => [a] -> Bool
allDifferent list = case list of
[] -> True
(x:xs) -> x `notElem` xs && allDifferent xs
Minor variant, using pattern matching directly in the equations:
allDifferent :: (Eq a) => [a] -> Bool
allDifferent [] = True
allDifferent (x:xs) = x `notElem` xs && allDifferent xs
I tend to stay away from partial functions like head,tail
, so the variants based on guards look worse to me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With