2

我是 Haskell 的初学者,在使用 Ord 时我错过了一个概念。我正在尝试通过下面的函数从 Haskell 的列表中唯一的对

pairs:: (Ord a) => [a] -> [(a,a)]
pairs[] = []
pairs(x:xs) = [(i, j) | i <- xs, j <- xs, i > j]

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

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

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

谢谢。

4

1 回答 1

7

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

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

因此,您可能想要使用:

pairs:: (Ord a) => [a] -> [(a,a)]
pairs xs = [(i, j) | i <- xs, j <- xs, i > j]

因此,我们在这里捕获了整个列表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]

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

于 2019-09-30T09:46:49.387 回答