Search code examples
listhaskellfunctional-programmingcomparison

Haskell - Checking if all list elements are unique


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?


Solution

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