I am a beginner in Haskell and I am missing a concept while using Ord. I am trying to unique pairs out of a list in Haskell through the function below
pairs:: (Ord a) => [a] -> [(a,a)]
pairs[] = []
pairs(x:xs) = [(i, j) | i <- xs, j <- xs, i > j]
So for example if i want to get the unique pairs of [4,3,1,2] i should get the output [(4,3),(4,1),(4,2),(3,1),(3,2),(2,1)]
but I am getting [(3,1),(3,2)] instead.
my question is, why is this skipping the first element of the list xs?
Thanks.
My question is, why is this skipping the first element of the list
xs
?
It is not skipping the first element of the list xs
. It is just skipping x
. (x:xs)
is a pattern where x
is the "head" of the list (the first item), whereas xs
is the tail of the list (a list containing the remaining elements).
You thus likely want to use:
pairs:: (Ord a) => [a] -> [(a,a)]
pairs xs = [(i, j) | i <- xs, j <- xs, i > j]
Here we thus capture the entire list xs
.
If the order does not matter much, we can make this a bit more efficient by calculating the minimum and maximum, and iterating over the tails:
import Data.List(tails)
order2 :: Ord a => a -> a -> (a, a)
order2 x y | x > y = (x, y)
| otherwise = (y, x)
pairs:: (Ord a) => [a] -> [(a,a)]
pairs xs = [order2 i j | (i:js) <- tails xs, j <- js, i /= j]
Here we thus first take an element i
, and the remaining elements are stored in js
. We then iterate over js
. If i
and j
are not the same, we use order2
to create a 2-tuple where the first item is larger than the second item.