我试图使用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)
答案 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]