Haskell - 列表理解也访问下一个元素

时间:2014-10-19 02:52:53

标签: haskell list-comprehension

我试图使用列表推导来返回与下一个不同的列表元素。到目前为止,我已经使用模式和警卫,但最终需要使用列表理解

所以fn [4,3,3,1,1,3,3,3]和[4,3,1,3]会返回[4,3,1]

这是我到目前为止只返回一个空列表

notEq'::[Int]->[Int]
notEq' il = [x | x <- il, fn il]
                where fn (a:b:xs) = a == b

编辑:在问题上进一步扩展,我希望它将每个元素与下一个元素进行比较,并将最后一个比较排除在[]之外。所以[4,3,3,1]会像这样(4,3,OK),(3,3,NO),(3,1,OK)与结果[4,3]

2 个答案:

答案 0 :(得分:2)

您所描述的功能和您提供的示例似乎不同意。

示例输出表明您正在寻找一个获取列表并返回仅包含不同元素的列表的函数。在这种情况下,您正在寻找nub

nub [4,3,3,1,1,3,3,3]
-- result is [4,3,1]

但是,您在英语和代码中描述的功能会获取一个列表并删除相邻的重复项。在这种情况下,您希望两个示例输入的结果都是[4,3,1,3],而不是[4,3,1]。在这种情况下,Haskell已经具有相邻,相等元素的group子序列的函数:

map head $ group [4,3,3,1,1,3,3,3]
-- result is [4,3,1,3]

如果你必须使用理解,也许这就足够了:

[ x | x:xs <- group [4,3,3,1,1,3,3,3] ]
-- result is [4,3,1,3]

现在您已经澄清了您想要做的事情,我认为tails将成为您的朋友:

let xs = [4,3,3,1,1,3,3,3] in
  [ a | a:b:_ <- tails xs, a /= b ]
-- result is [4,3,1]

我真的不明白你为什么要排除最后一个元素。如果您偶然想要包含它,那么它很容易适应:

let xs@(x:_) = [4,3,3,1,1,3,3,3] in
  x : [ b | a:b:_ <- tails xs, a /= b ]
-- result is [4,3,1,3]

答案 1 :(得分:1)

考虑使用其后继方法压缩列表中的每个元素,并过滤那些第一项和第二项不同的对,如下所示,

notEq' :: [Int] -> [Int]
notEq' xs = map (fst) . filter (\(a,b) -> a /= b) $ zip xs (drop 1 xs)

要获取带标签的列表,请考虑这一点,

pairing :: Eq t => (t, t) -> (t, t, [Char])
pairing (x,y) = (x,y,label)
  where
    label = if (x /= y) then "OK" else "NO"

等等

map (pairing) $ zip xs (drop 1 xs)

[4,3,3,1,1,3,3,3]会传递

[(4,3,"OK"),(3,3,"NO"),(3,1,"OK"),(1,1,"NO"),(1,3,"OK"),(3,3,"NO"),(3,3,"NO")]

<强>更新

使用理解,像这样,

notEq' :: [Int] -> [Int]
notEq' xs = [ x | (x,y) <- zip xs (drop 1 xs), x /= y ]