如何使用列表推导精确添加第2和第3个子列表

时间:2014-12-07 17:32:28

标签: haskell list-comprehension

明天我正在参加期末考试。我正在尝试几个奇怪的例子。例如,我得到了一个这样的子列表列表:[[1, 2], [2, 3, 4], [5, 6], [7, 8], [8, 9, 10]]。我想将第二个和第三个子列表添加到一起,并使用列表推导返回它们的总和。我尝试了很多东西,但我无法成功。

我意识到列表理解会为每个子列表生成一个cons对,并尝试添加每个cons对的第二个和第三个元素。但这不是我想要的。我想输出[20],因为2 + 3 + 4 + 5 + 6 = 20。

我写了这个,我试图只在一个cons对中添加第二个子列表。但是,没有办法生成第三个子列表。所以我有点卡住了。:

sumTwoThree::[[Int]]->[Int]
sumTwoThree list = [(x + xs) | (x:xs)<-(list!!1)]

我也写了这个:

sumTwoThree::[[Int]]->[Int]
sumTwoThree list = [head xs + head (tail xs) | (x:xs)<-list, (length xs > 1)]

但这仅生成至少包含3个元素的子列表,然后将这些子列表的第2个和第3个元素相加。

1 个答案:

答案 0 :(得分:2)

基本上,您想要过滤掉不是第二个或第三个的子列表,然后将它们包含在结果中。之后,您使用sum。像这样:

sumTwoThree xs = sum [x | (i, sub) <- zip [1,2..] xs,
                          i == 2 || i == 3,
                          x <- sub]

如果不使用sum功能,则无法完成此操作。这是因为列表理解只是使用列表monad的语法糖。而且你必须折叠一个列表来计算其元素的总和。

如果你想真正了解列表理解是什么,那么了解列表monad,甚至尝试理解它是如何工作的:

foo []     = [[]]
foo (x:xs) = [x':xs' | x' <- x, xs' <- foo xs]

然后观察它的作用:

Main*> foo ["123", "abc"]
["1a","1b","1c","2a","2b","2c","3a","3b","3c"]