Reputation: 53
So i am supposed to remove direct duplicates that are next to each other from a list. For example 1,3,3,3,2,4,4,2,4] = [1,3,2,4,2,4] or [63,65,65,64,65,63,65,65,64,64,65] = [63,65,64,65,63,65,64,65]. My code just removes all duplicates. I think my problem is that i compare with elem and i need a function that only compares with the next element.
module Blueprint where
import Prelude
compress :: [Int] -> [Int]
compress [] = []
compress (x:xs) | x `elem` xs = compress xs
| otherwise = x : compress xs
Upvotes: 1
Views: 604
Reputation: 152757
The group
function finds adjacent equal values and groups them together. So your function may be implemented as
compress = map head . group
At first, it may look dangerous to use head
; however, a promise of group
is that each element it returns is a non-empty list.
Upvotes: 4
Reputation: 48591
I've been getting a lot of bang from this little fold technique lately:
smash :: Eq a => [a] -> [a]
smash xs = foldr go (`seq` []) xs Nothing
where
go x r (Just prev)
| x == prev = r (Just x)
go x r _ = x : r (Just x)
Upvotes: 1
Reputation: 1500
Right now you are checking if x has a duplicate in the rest of the function. You actually want to check if the next element is a duplicate. You can do this by looking at the first two elements of a list not just the first one.
compress :: [Int] -> [Int]
compress [] = []
compress [x] = [x]
compress (x:x2:xs) | x == x2 = compress (x2:xs)
| otherwise = x : compress (x2:xs)
Upvotes: 6