Haskell列表输出中缺少第一个元素

Noo*_*pty 2 sorting haskell ord

我是Haskell的初学者,在使用Ord时缺少一个概念。我正在尝试通过以下功能在Haskell列表中唯一的对

pairs:: (Ord a) => [a] -> [(a,a)]
pairs[] = []
pairs(x:xs) = [(i, j) | i <- xs, j <- xs, i > j]
Run Code Online (Sandbox Code Playgroud)

因此,例如,如果我想获得[4,3,1,2]的唯一对,我应该得到输出[[4,3),(4,1),(4,2),(3,1) ,(3,2),(2,1)]

但我却得到[(3,1),(3,2)]。

我的问题是,为什么这会跳过列表xs的第一个元素?

谢谢。

Wil*_*sem 7

我的问题是,为什么要跳过列表的第一个元素xs

它不会跳过列表的第一个元素xs。它只是跳过x(x:xs)是一个模式,其中x是列表的“头部”(第一项),而是列表xs尾部(包含其余元素的列表)。

因此,您可能想使用:

pairs:: (Ord a) => [a] -> [(a,a)]
pairs xs = [(i, j) | i <- xs, j <- xs, i > j]
Run Code Online (Sandbox Code Playgroud)

因此,这里我们捕获了整个列表xs

如果顺序没什么大不了,我们可以通过计算最小值和最大值并遍历尾部来提高效率:

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]
Run Code Online (Sandbox Code Playgroud)

因此,这里我们首先获取一个元素i,其余元素存储在中js。然后我们遍历js。如果ij不相同,我们order2将创建一个2元组,其中第一个项目大于第二个项目。