I am pretty new to Haskell and I have a question. How can I write a function to return all the unique possible pairs of a list? Like: [1,2,3,4] -> [(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]
Asked
Active
Viewed 6,697 times
9
-
4how should your function behave on the input [1,1,2,3]? – epsilonhalbe Dec 02 '15 at 13:58
-
it never happens. Because the elements in the list are all unique. – Negar Alinaghi Dec 02 '15 at 14:02
3 Answers
37
Using a list comprehension is the easiest way.
import Data.List
pairs :: [a] -> [(a, a)]
pairs l = [(x,y) | (x:ys) <- tails l, y <- ys]
This only generates the relevant pairs so you don't have to filter out any duplicates as a separate step. tails [1,2,3,4]
generates the lists of tails [[1,2,3,4], [2,3,4], [3,4], [4], []]
and the list comprehension picks the first element from each tail and pairs it with the rest of the elements in that tail.
-
2This should be the answer. The other answers require the list's elements to be have an `Ord` or `Eq` instance. – Franky Dec 02 '15 at 14:32
2
You can use the nub
function:
import Data.List
uniq_pairs l = nub [(x,y) | x <-l, y<-l, x < y]
Output:
*Main> uniq_pairs [1,2,3,4]
[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]

thor
- 21,418
- 31
- 87
- 173
-
-
@NegarAlinaghi if elements of `l` are unique, using `nub` here is useless. – lisyarus Dec 02 '15 at 14:25
-
@lisyarus But, in general, if the list does have duplicate elements, `nub` will be needed to get unique pairs. – thor Dec 02 '15 at 14:30
2
Looking at your example, this seems to be what you want
unique_pairs l = [(x,y) | x <- l, y <- l, x < y]
By the way, these are not just unique pairs, but unique pairs up to transposition.

lisyarus
- 15,025
- 3
- 43
- 68