2017-08-12 6 views
0

簡単な質問、それを行う方法がわかりません。ハスケル:リスト内の前の要素を覚えている

私はData.Listからsum関数のより限定されたバージョンを書いて、次のコードを持っている:elemIndexのX引数が範囲にあった場合、私はこれがうまくいくと信じて

-- Sum the contents of a list 

sum' :: Num a => [a] -> a 

sum' [] = 0 

sum' (x:xs) = x + sum' rest where 
       rest = drop (succ (elemIndex x xs)) xs 

を現在のリスト要素の

私はそれは、彼が折り畳み式のカバー、またはほとんどのHaskellのアイデアの前に書かれたことが予想Haskellのでグラハムハットンのプログラミングに問題があるため、できるだけ基本として、折り畳み式を使用せずにこれをやりたいです。

+0

を。これは、折り目を使用する正確な状況です。私は折り畳みが「原始的」であると考えています。 – Carcigenicate

+0

リストを合計するには、 'foldl + numbers'だけです。あなたがそれらを数回使用すると、折り畳みは非常に簡単です。 – Carcigenicate

+2

あなたは数字のリストを合計しようとしていますか?それがあなたの質問なら、私は答えを書くでしょう。あなたが何をしようとしているのかはっきりしていません。 – Carcigenicate

答えて

3

あなたは加算機能を書きたい場合は、「手動」、それは単に最初の要素に加えて、残りの要素の和になります:

sum' :: Num a => [a] -> a 

-- The sum of an empty list is 0 
-- The "base case" of the recursion 
sum' [] = 0 

-- The sum of a non-empty list is equal to the first element 
-- plus the sum of the rest of the list 
sum' (x:xs) = x + (sum' xs) 

いいですが、しばらくして、あなたがよあなたはアキュムレータを維持しながら、リスト全体をループするという、この正確なパターンをたくさんすることに気づくでしょう。この場合、数値の合計はアキュムレータです。 。fold sがでてくるところ

これは折り目がどのように動作するかの完全な説明は疑問を超えていますが、折り目を使用して番号のリストを合計するには、単に書くことができます。

sum' :: Num a => [a] -> a 
sum' xs = foldl (+) 0 xs 

基本的にそう

foldl (+) 0 [1, 2, 3, 4, 5] 

は(LEFで0点に注意してくださいとして基本的に同じことです、あなたはリスト内の各要素の間にそれを与える関数を挿入t。それは)開始の合計です:

0 + 1 + 2 + 3 + 4 + 5 

は、折り目の詳細については、私は答えを書きました(他の多くの間で)here。それは一見価値がある。

+1

1. foldlのあなたの説明は素晴らしいです。2. Iあなたの最初の答えと同じくらい簡単に書くことができるとは思わなかった3.ハスケルのコミュニティは他の人よりも多くの理解があるように見える!ありがとうございます – Typhon

+0

Np。私は注意する必要がありますあなたが 'foldl'に与える関数は、数学演算子ほどシンプルである必要はありません。フォールド+匿名関数=非常に簡潔なループ。 – Carcigenicate

1

あなたはそれがさらに簡単にあなたをすることができカリー理解していれば:

sum' = foldl (+) 0 
関連する問題