2011-01-19 22 views
11

リストの実行合計を返す関数を作成します。例えば実行中の[1,2,3,5]は[1,3,6,11]です。私はこのリストの中のすべての値の最終的な合計を返すことができる以下の関数を書いています。Haskellでのリスト累積合計の計算

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

答えて

9

あなたは単に、各ステップでの結果にa+xを付加し、基本ケースとして、空のリストを使用して、リストを生成するために、あなたの機能を調整することができます。

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

この種を表現するためにHaskellのより多くの慣用句ですが折りたたみやスキャンのようなもの。

25

は、私はあなたが、返されたリストに、それぞれの中間値をリスト全体に与えられた関数を適用し、報告します

scanl1 (+) *your list here* 

scanl1ようscanl1との組み合わせ(+)ので、何かをしたいと思います。

と同様に、擬似コードでそれを書くために、

scanl1 (+) [1,2,3] 

のような出力リストを希望:

[1, 1 + 2, 1 + 2 + 3] 

言い換えれば、

[1, 3, 6] 

Learn You A Haskellはたくさん持っていますスキャン、折りたたみ、およびはるかに多くのハスケルのお菓子の素晴らしい例と説明があります。

これが役に立ちます。

3

scanl1は明らかに「標準的な」解決策ですが、まだあなたがfoldlのでそれを行うことができる方法を参照することは有益である:

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

またはpointfree:ここ

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

は醜い野獣です力のアプローチ:

sumList xs = reverse $ acc $ reverse xs where 
    acc [] = [] 
    acc (x:xs) = (x + sum xs) : acc xs 

を使用しているかわいい:

sumList xs = tail $ map sum $ inits xs 

再度のpointfree:別の質問に関連

sumList = tail.map sum.inits 
+0

@ sepp2k:リストの右側から始めると、要素の合計がどのように残っていますか? – Landei

+0

@Lamdei:申し訳ありませんが、私は正しいとは思っていませんでした。しかし、怠け者ではないことは、foldl(またはあなたのブルートフォースアプローチ)を使わないのに十分な理由です。 – sepp2k

+1

なぜ '逆'ですか? 'sumList =(\ snd \' [])です。 foldl(\\(a、k)x - >(a + x、k。(a + x :)))(0、id) 'は順方向にうまく動作します。 – ephemient

0

私はこの方法を見つけた:

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

私はそれも非常に効率的だと思います。