Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 如何对列表中的每2个元素求和?_List_Haskell - Fatal编程技术网

List 如何对列表中的每2个元素求和?

List 如何对列表中的每2个元素求和?,list,haskell,List,Haskell,基本上,我想执行以下操作: [1,2,3,4,5,6,7]->[3,7,11,7] 在上面的示例中,列表末尾的元素被单独保留,因为列表的长度是奇数,因此无法添加任何元素 我想把这个列表变成一个元组列表,比如[1,2,3,4]->[(1,2),(3,4)],然后对每个元组执行加法,但我不知道怎么做,也不确定它是否可以处理奇数长度的列表 当然,有一种方法可以将列表中的每两个元素相加。一种简单的方法是通过基本的递归定义: sumPairs :: Num a => [a] -> [a] --

基本上,我想执行以下操作: [1,2,3,4,5,6,7]->[3,7,11,7]

在上面的示例中,列表末尾的元素被单独保留,因为列表的长度是奇数,因此无法添加任何元素

我想把这个列表变成一个元组列表,比如[1,2,3,4]->[(1,2),(3,4)],然后对每个元组执行加法,但我不知道怎么做,也不确定它是否可以处理奇数长度的列表


当然,有一种方法可以将列表中的每两个元素相加。

一种简单的方法是通过基本的递归定义:

sumPairs :: Num a => [a] -> [a]
-- first, we deal with the base case
sumPairs [] = []
-- next we deal with the odd length list base case
sumPairs [x] = [x]
-- now we can recurse!
sumPairs (x:y:list) = (x+y) : sumPairs list
但是,如果您想通过组合现有函数来实现这一点,您可以在hoogle中搜索
[a]->[(a,a)]
()以查看是否存在任何相关函数

不幸的是,似乎没有。如果您想要更具组合性的内容,可以编写以下函数:

pairUp :: Num a => [a] -> [(a,a)]
pairUp [] = []
pairUp [x] = [(x, 0)]
pairUp (x:y:list) = (x,y) : pairUp list

sumPairs :: Num a => [a] -> [a]
sumPairs = map (uncurry (+)) . pairUp
或者,如果你想变得更普通

pairUp :: Monoid a => [a] -> [(a,a)]
pairUp [] = []
pairUp [x] = [(x, mempty)]
pairUp (x:y:list) = (x,y) : pairUp list

mergePairs :: Monoid a => [a] -> [a]
mergePairs = map (uncurry (<>)) . pairUp
甚至

combinePairs :: (a -> a -> a) -> [a] -> [a]
combinePairs _ [] = []
combinePairs _ [x] = [x]
combinePairs _ (x:y:list) = f x y : combinePairs list

sumPairs :: Num a => [a] -> [a]
sumPairs = combinePairs (+)

对于这个问题,我想我应该回到显式递归:

sumPairs :: Num a => [a] -> [a]
sumPairs (x:y:ys) = x+y:sumPairs ys
sumPairs xs = xs
很好也很简单:如果至少有两个元素,将它们相加,然后递归完成其余的工作。否则(意味着有零个或一个元素),只需返回您得到的相同列表。

非常简短

map sum . chunksOf 2

那么这里到底发生了什么?我还是Haskell的新手,所以可视化其中一些函数是相当困难的。使用第一个示例,如果我想将函数声明更改为pairs:(Integer->Integer->Integer)->[Integer]->[Integer],而不是求和,请执行(+)、(-)、(*)等操作。我该怎么改变定义呢?没关系,我明白了!我只是将uu与空列表和奇数列表一起传入,然后将f与底格一起传入,然后对递归块执行sumf list。其实很简单!
map sum . chunksOf 2