通过累积添加另一个列表的元素来创建列表:Haskell

时间:2011-11-09 00:41:21

标签: haskell

我似乎无法找到有关高阶函数的任何信息。我找到了几个地方的cadd,但在haskell api中找不到任何信息。

我只是想获取一个浮动列表,并通过累加每个浮点数创建另一个列表。原始列表将始终为零。所以,如果我有[0,2,5,9]的列表,我会得到[0,2,7,16]的列表。

accumulateTime :: [Float] -> [Float]
accumulateTime (x:xs) = cadd????

我有这段代码的其他部分做事但我似乎无法如何制作这个列表。

4 个答案:

答案 0 :(得分:20)

听起来您想要scanl的变体,它与foldl相关,但会创建一个中间结果列表。因此,foldl (+) 0总结一个列表时,scanl (+) 0会创建一个部分总和列表。在这里,你可能想要scanl1 (+),它在开头不会增加额外的零。

Prelude> scanl1 (+) [0, 2, 5, 9]
[0,2,7,16]

答案 1 :(得分:5)

我认为能够将这个代码的命令版本翻译成功能样式是一个很好的技巧,从长远来看。以下是我用其中一种野蛮的命令式语言解决这个问题的方法:

var acc = 0;
for each x in xs:
    acc = x + acc
    yield acc

请注意,我们在这里有两个变量 - 数字列表和滚动总和。当我们将这段代码转换为函数样式时,通常必须将循环转换为(尾部)递归,并将变量转换为函数参数(因为这是他们可以“变异”的唯一地方)。

accum_helper acc list

我们现在可以尝试解决基本情况......

accum_helper acc [] = ...

......递归案例

accum_helper acc (x:xs) = ...

...最后使用父函数进行变量初始化

accumulate xs = accum_helper 0 xs

答案 2 :(得分:3)

请注意,fold functions可以使用任何类型的累加器变量 - 甚至是一个元组,其中一个元素是累积和,第二个元素是先前累积和的列表。

答案 3 :(得分:3)

方式不如哈马尔的答案那么酷,但另一种解决方案:

accumulate list = [sum $ take n list | n <- [1 .. length list]]