5

I have heard the term 'list difference' (\\) operator in Haskell but still don't quite know how to get my head around it. Any examples or ideas?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
maclunian
  • 7,893
  • 10
  • 37
  • 45

4 Answers4

9

The (\\) operator (and the difference function) implements set difference, so, if you have two lists, a and b, it returns only those elements of a that are not in b, as illustrated:

enter image description here

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
  • 5
    But it actually implements multi-set difference; the argument lists are allowed to contain the same element multiple times. – augustss May 29 '11 at 15:39
  • if I have this declaration : diff :: (Eq a) => [a] -> [a] -> [a] and I want to find the difference between 2 lists? How should I proceed? – Madalina May 11 '17 at 14:40
8

Simply put, it takes two lists, goes through the second and for each item, removes the first instance of the same item from the first list.

> [1..10] \\ [2, 3, 5, 8]
[1,4,6,7,9,10]
> [1, 2, 1, 2, 1, 2] \\ [2]
[1,1,2,1,2]
> [1, 2, 1, 2, 1, 2] \\ [2, 2]
[1,1,1,2]
> [1, 2, 1, 2, 1, 2] \\ [2, 2, 1]
[1,1,2]
Samir Talwar
  • 14,220
  • 3
  • 41
  • 65
2

xs \\ ys is all the elements in xs that are not in ys. Maybe a list comprehension will clarify this:

xs \\ ys = [ x | x <- xs, x `notElem` ys ]

or, if you could do this in Haskell,

xs \\ ys = [ x | x `elem` xs, x `notElem` ys ]

This comes from set theory's set difference. The basic idea is that you are "subtracting" one collection of elements from another, hence the term "difference".

Aaa
  • 1,854
  • 12
  • 18
  • if I have this declaration : diff :: (Eq a) => [a] -> [a] -> [a] and I want to find the difference between 2 lists? How should I proceed? – Madalina May 11 '17 at 14:39
0

Suppose, you have a list of things, for example cities. Let's take for instance this list:

a = ["London","Brussels","Tokio","Los Angeles","Berlin","Beijing"]

Now you want to remove all cities that are in Europe. You know, that those cities are in Europe:

b = ["Glasgow","Paris","Bern","London","Madrid","Amsterdam","Berlin","Brussels"]

To get a list of cities in a, that are not in Europe, so that are not in b, you can use (\\):

a \\ b = ["Tokio","Los Angeles","Beijing"]
Samir Talwar
  • 14,220
  • 3
  • 41
  • 65
fuz
  • 88,405
  • 25
  • 200
  • 352
  • how would do this without the difference operator ? – matt Jan 01 '16 at 21:29
  • 2
    @matthias You can implement `(\\)` as `a \\ b = filter (not . flip elem b) a`. – fuz Jan 01 '16 at 21:32
  • sorry 1 more thing... could you write that in non point free please? – matt Jan 01 '16 at 22:16
  • @matthias That is about as point-free as it can get. I can add one more lambda if you like: `a \\ b = filter (\x -> not (x \`elem\` b)) a`. – fuz Jan 01 '16 at 22:17
  • oh thanks.. I actually did not want point free. I don't know that its called (new to this). I find point free harder to understand. I think the way you wrote it now is easier to understand. – matt Jan 01 '16 at 23:36
  • @matthias Sorry, I meant “that's about as non point-free as it can get” but I mixed up. I'm happy that I was able to help you. – fuz Jan 01 '16 at 23:40
  • if I have this declaration : diff :: (Eq a) => [a] -> [a] -> [a] and I want to find the difference between 2 lists? How should I proceed? – Madalina May 11 '17 at 14:40
  • @Madalina Difference as in “symmetric difference”? – fuz May 11 '17 at 14:54
  • @fux: I have 2 lists, a and b, it returns only those elements of a that are not in b – Madalina May 11 '17 at 14:58
  • @Madalina Then just use `diff = (\\)` whith `(\\)` from `Data.List`. – fuz May 11 '17 at 15:01