I'm working on learning Haskell, and one of the simple exercises I put myself through to this end is writing a function that deduplicates a list, removing all of the duplicate elements of a list such that every element in the output list is both unique and present in the original list.
My inelegant code for doing this is as follows:
dedup [] = []
dedup (n:ns) = theDedup n ns ns
where theDedup n ns remains
| ns == [] = n : []
| remains == [] = n : theDedup (head ns) (tail ns) (tail ns)
| n == head remains = theDedup (head ns) (tail ns) (tail ns)
| otherwise = theDedup n ns $ tail remains
For every element of the original list n:ns
, theDedup
takes that element and recursively compares it to every other (remains
), while keeping a copy of the items left to deduplicate as ns
. When remains
has run out, the current n
has been compared to every other value and so must be unique, and when ns
has run out, the entire list has been deduplicated, so n
must be unique.
This is a rather confusing way of expressing a rather simple algorithm. How can it be done better?