1

私はリストを繰り返し、すべての数字を二乗してそれらを足し合わせようとしています

sumsq  (x:xs) = 
let total = 0
loop length(x:xs) (x:xs) total


loop 0 (x:xs) = return ()
loop n (x:xs)  total = 
do
    let 
        sq = ((x:xs)!!n)^2
        total = total + sq
    loop ((n-1) (x:xs) total)

しかし、私は得てparse error in loopいます。どこが間違っていますか?

また、これを行うためのより良い方法はありますか?

4

4 に答える 4

3

私があなたを正しく理解していれば、これをmapandで簡単に行うことができますsum

Prelude> let myFun = sum . map (^2)
Prelude> myFun [1, 2, 3]
14

またfoldl1はとラムダを使用:

Prelude> let myFun' = foldl1 (\s x -> s + x^2)
Prelude> myFun' [1, 2, 3, 4]
30
于 2013-10-07T15:58:48.837 に答える
3

確かに、このようなものは通常のアプローチでしょうか?

sumSquared :: [Integer] -> Integer
sumSquared [] = 0
sumSquared (x:xs) = (x * x) + sumSquared xs

foldrまたは、 , またはsumandを使用してこれをさらに簡潔にすることもできますmap(@soonの回答のように)

于 2013-10-07T15:59:52.707 に答える
3

まず第一に、あなたはスペースが恋しいです!それは重要です。

in第二に、あなたはから忘れますlet ... inin-表記では使用できませんdoでした:

sumsq  (x:xs) = 
   let total = 0 in
   loop length(x:xs) (x:xs) total

x第三に、 andxsフォームを使用しません(x:xs):

sumsq  xs = 
    let total = 0 in
    loop (length xs) xs total

length xsそして、私たちは1つのブロックで団結します。4番目です。

第 5 に、ループの引数は 2 つではなく 3 つです。

loop 0 xs total  = return total

第六に、(!!) 0から働くけど、1から使うんだよ(xs !! (n -1))

第7に、モナドを使う必要はなく、再帰だけです。returnだから、から取り除くdo

第8。あなたは無限再帰を持っていますtotal = total + smth

第 9 に、引数をタプルとして使用できないため、最終的な作業結果は次のようになります。

sumsq  xs = 
    let total = 0 in
    loop (length xs) xs total


loop 0 xs total = total
loop n xs total = loop (n-1) xs total1
    where 
        sq = (xs !! (n -1)) ^2
        total1 = total + sq

更新しました

複雑さについて話している場合O(n^2)、コメントで言及されているように、それは良くありません。各要素に対して、この要素を探します。nループ関数を単純化し、引数を取り除くことができます。

loop []     total = total
loop (x:xs) total = loop xs total1
    where 
        sq = x ^ 2
        total1 = total + sq

そして私たちのsumsq関数は次のように書きます:

sumsq  xs = loop xs 0

PSこれは実装がはるかに簡単な機能ですsumsq = sum. map (^ 2)

于 2013-10-07T15:56:06.580 に答える