计算Haskell中的列表累积和

计算Haskell中的列表累积和,haskell,Haskell,编写一个函数,返回列表的运行和。e、 g.运行[1,2,3,5]是[1,3,6,11]。我在下面写了这个函数,它可以返回列表中所有值的最终和。那么我如何将它们逐个分开呢 sumlist' xx=aux xx 0 where aux [] a=a aux (x:xs) a=aux xs (a+x) 我认为您需要和(+)的组合,所以 scanl1 (+) *your list here* scanl1将在一个列表中应用给定的函数,并将每个中间值报告到返回的列表中 比如

编写一个函数,返回列表的运行和。e、 g.运行[1,2,3,5]是[1,3,6,11]。我在下面写了这个函数,它可以返回列表中所有值的最终和。那么我如何将它们逐个分开呢

sumlist' xx=aux xx 0
    where aux [] a=a
          aux (x:xs) a=aux xs (a+x)

我认为您需要和
(+)
的组合,所以

scanl1 (+) *your list here*
scanl1将在一个列表中应用给定的函数,并将每个中间值报告到返回的列表中

比如,用伪代码写出来

scanl1 (+) [1,2,3]
将输出如下列表:

[1, 1 + 2, 1 + 2 + 3]
换句话说

[1, 3, 6]
有很多很好的例子和描述的扫描,折叠,和更多的哈斯克尔的好东西


希望这能有所帮助。

您可以调整函数以生成列表,只需在每个步骤的结果前面加上
a+x
,并使用空列表作为基本情况:

sumlist' xx = aux xx 0
    where aux [] a = []
          aux (x:xs) a = (a+x) : aux xs (a+x)

不过,Haskell更习惯于将此类内容表示为折叠或扫描。

虽然scanl1显然是“规范”解决方案,但了解如何使用foldl实现这一点仍然很有意义:

sumList xs = tail.reverse $ foldl acc [0] xs where 
  acc (y:ys) x = (x+y):y:ys
或无点:

sumList = tail.reverse.foldl acc [0] where 
  acc (y:ys) x = (x+y):y:ys
sumList = tail.map sum.inits
这是一种丑陋的暴力手段:

sumList xs = reverse $ acc $ reverse xs where
  acc [] = []
  acc (x:xs) = (x + sum xs) : acc xs
使用
inits
,有一个可爱(但性能不太好)的解决方案:

sumList xs = tail $ map sum $ inits xs
同样是无意义的:

sumList = tail.reverse.foldl acc [0] where 
  acc (y:ys) x = (x+y):y:ys
sumList = tail.map sum.inits

与我发现的另一个问题相关:

rsum xs = map (\(a,b)->a+b) (zip (0:(rsum xs)) xs)

我认为它甚至非常有效。

@sepp2k:如果从列表的右侧开始,那么如何得到左边元素的总和?@Lamdei:对不起,我没想对。然而,不偷懒仍然是不使用foldl(或你的暴力方法)的一个很好的理由。为什么
反向
<代码>sumList=(`snd`[])。foldl(\\(a,k)x->(a+x,k.(a+x:))(0,id)
在前进方向上工作得很好。@ephemient:这很酷,我没想到,但对初学者来说可能太复杂了。