Haskell中的累积和

时间:2014-05-23 15:04:14

标签: haskell

我试图使用inits函数创建一个函数:

 [x1,x2,x3,x4,x5....] ==  [0,x1, x1+x2, x1+x2+x3, x1+x2+x3+x4, (x1+x2+x3+x4+x5) ....]

这是我的尝试:

sums:: [Int]->[Int]
sums (x:xs)  = [x] ++ map foldr 0 (+)  initial xs


inits1:: [int] -> [[int]]
inits1 []     = [[]]
inits1 (x:xs) = [[x]] ++ map (x:) (initial xs)

3 个答案:

答案 0 :(得分:4)

您可以使用标准库吗?

sums :: Num a => [a] -> [a]
sums = scanl (+) 0

答案 1 :(得分:3)

使用inits是一种不好的方式。

想一想。如果你是在纸上做的,你就不会把第一个数字加起来,然后是前两个,然后是前三个,然后是前四个。

这很愚蠢,因为当你添加前四个时,你必须重新添加前三个,即使你之前已经添加过它们。

相反,您刚刚开始添加它们,保留总数,这些总数将形成您的结果。

所以你应该使用scanl1,就像foldl1一样,但会为你提供结果:

sums = scanl (+) 0

避免使用库函数可以更好地完成它(以及scanl的运作方式:

sums2 ls = sums_worker 0 ls where
  sums_worker acc (l:ls) = acc:(sums_worker (acc + l) ls)
  sums_worker acc [] = [acc]

答案 2 :(得分:1)

inits会提供列表的所有初始细分,sum会给出一个数字列表的总和,因此您的sums可以这样定义:

sums = map sum . inits

实施例

> sums [1..10]
[0,1,3,6,10,15,21,28,36,45,55]