patternModerate
Implementing nub (distinct)
Viewed 0 times
distinctimplementingnub
Problem
I've implemented the following
Example:
Surely there must be a cleaner way?
nub' or "give distinct elements of list" function:nub' :: (Eq a) => [a] -> [a]
nub' [] = []
nub' xs = nubHelper xs []
nubHelper :: (Eq a) => [a] -> [a] -> [a]
nubHelper [] acc = acc
nubHelper (y:ys) acc = if(contains y acc)
then nubHelper ys acc
else nubHelper ys (acc ++ [y])
where contains match acc =
foldl (\as x -> if(y == x) then True else as) False accExample:
*Main> nub' [1,2,1,1,1,1,3,4,3,1]
[1,2,3,4]Surely there must be a cleaner way?
Solution
For the "official" answer, you can go straight to the GHC source for
Some of the differences that stand out are:
nub:nub :: (Eq a) => [a] -> [a]
nub l = nub' l []
where
nub' [] _ = []
nub' (x:xs) ls
| x `elem` ls = nub' xs ls
| otherwise = x : nub' xs (x:ls)Some of the differences that stand out are:
- Use a
whereclause to scope your helper function, and name it with a "prime" symbol. In your case, I guess the helper would benub''. The helper's type can then be automatically inferred.
- Use pattern matching instead of if-then-else.
- Your
containshelper is just theelembuiltin. They chose to writexelemlsinstead ofelem x ls, probably to read more smoothly.
- It's more natural / efficient to prepend than to append elements to a list. Instead of building
accas the result as a list of wanted elements, they buildlsas the list of elements to exclude in future encounters.
Code Snippets
nub :: (Eq a) => [a] -> [a]
nub l = nub' l []
where
nub' [] _ = []
nub' (x:xs) ls
| x `elem` ls = nub' xs ls
| otherwise = x : nub' xs (x:ls)Context
StackExchange Code Review Q#48101, answer score: 12
Revisions (0)
No revisions yet.