Reputation: 519
I'm trying to use list comprehension to return the list elements that differ from the next. So far I've got it working with patterns and guards but ultimately need to use list comprehension
So fn [4,3,3,1,1,3,3,3] and [4,3,1,3] would return [4,3,1]
This is what I've got so far which just returns an empty list
notEq'::[Int]->[Int]
notEq' il = [x | x <- il, fn il]
where fn (a:b:xs) = a == b
Edit: Expanding more on the question, I want it to compare each element to the next and exclude the last comparison to []. So [4,3,3,1] would go something like this (4,3,OK), (3,3,NO), (3,1,OK) with the result [4,3]
Upvotes: 1
Views: 2574
Reputation: 20435
Consider zipping each element of the list with its successor and filtering those pairs whose first and second item differ, like this,
notEq' :: [Int] -> [Int]
notEq' xs = map (fst) . filter (\(a,b) -> a /= b) $ zip xs (drop 1 xs)
For getting a list with labels, consider this,
pairing :: Eq t => (t, t) -> (t, t, [Char])
pairing (x,y) = (x,y,label)
where
label = if (x /= y) then "OK" else "NO"
and so
map (pairing) $ zip xs (drop 1 xs)
for [4,3,3,1,1,3,3,3]
would deliver
[(4,3,"OK"),(3,3,"NO"),(3,1,"OK"),(1,1,"NO"),(1,3,"OK"),(3,3,"NO"),(3,3,"NO")]
Update
Using a comprehension, like this,
notEq' :: [Int] -> [Int]
notEq' xs = [ x | (x,y) <- zip xs (drop 1 xs), x /= y ]
Upvotes: 1
Reputation: 33029
The function you're describing and the example you gave seem to disagree.
The example output suggests that you're looking for a function that takes a list and returns a list of only the distinct elements. In that case, you're looking for nub
:
nub [4,3,3,1,1,3,3,3]
-- result is [4,3,1]
However, the function you describe in English and in your code takes a list and removes adjacent duplicates. In that case, you would expect the result for both example inputs to be [4,3,1,3]
, not [4,3,1]
. In that case, Haskell already has a function to group
subsequences of adjacent, equal elements:
map head $ group [4,3,3,1,1,3,3,3]
-- result is [4,3,1,3]
If you must use a comprehension, maybe this will suffice:
[ x | x:xs <- group [4,3,3,1,1,3,3,3] ]
-- result is [4,3,1,3]
Now that you've clarified what you want to do, I think tails
would be your friend here:
let xs = [4,3,3,1,1,3,3,3] in
[ a | a:b:_ <- tails xs, a /= b ]
-- result is [4,3,1]
I really don't understand why you want to exclude the last element. If you by chance wanted to include it, it would be easy to accommodate:
let xs@(x:_) = [4,3,3,1,1,3,3,3] in
x : [ b | a:b:_ <- tails xs, a /= b ]
-- result is [4,3,1,3]
Upvotes: 2