I'm trying to implement union from the standard Data.List library. I know it's reinventing the wheel, but reimplementing functions is how I learn things. Any feedback at all would be helpful!

union' :: (Eq a) => [a] -> [a] -> [a]
union' [] _ = []
union' _ [] = []
union' xs ys = nub' $ xs ++ ys where 
    nub' [] = []
    nub' (x:xs)
        | not $ x `elem` xs = x : nub' xs
        | otherwise = nub' xs

This code works, but it strikes me as verbose. union is the opposite of intersect, which does not require a helper where statement:

intersect' :: (Eq a) => [a] -> [a] -> [a]
intersect' [] _ = []
intersect' _ [] = []
intersect' (x:xs) list
    | x `elem` list = x : intersect' xs list
    | otherwise = intersect' xs list

How can I make my union function resemble the elegance of my intersect function?

Revision here

  • \$\begingroup\$ I am glad you were able to clean up your code. If you would like a review on the changes, please post another question rather than appending the new code to the current question. \$\endgroup\$
    – user34073
    Commented Feb 27, 2016 at 18:46

1 Answer 1


Your base cases are both invalid and unnecessary:

union' [] _ = []
union' _ [] = []

There isn't anything bad about using where, especially when you consider that union' needs no base cases. Your question is, really, whether union' should be implemented using some kind of nub or not. If you're as an exercise, why wouldn't you want to reimplement nub as well?

The real question you should be asking is how to avoid ++.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.