2017-05-15 30 views
0

リストのすべての要素の合計を計算する次のコードがあります。末尾再帰の構文解析エラーHaskell

sum_list_tail :: [Int] -> Int 
sum_list_tail (x:xs) = inc(x:xs, 0) 
          where inc(x:xs, a) = 
           if (x:xs == []) then a 
            else inc(xs, a+x) 

私はこの問題を解決するためにテール再帰を使用しようとします。

私はこのエラーparse error (possibly incorrect indentation or mismatched brackets)がこの行で発生していif (x:xs == []) then a

私が間違ってやっているかを調べることができません。

+0

タブとスペースを混在させていますか?ハスケルはそれを嫌っている。またこのテスト 'x:xs == []'は定数 'False'です。おそらく、あなたが書くことを意図したものではないでしょう。 – gallais

答えて

3

構文エラーは、スペースがWHERE句に等しくないという事実によるものである:if文はwhereラインより少ないスペースを持っています。あなたは、このように簡単にwhere句でワンライナーを書くことで、それを解決することができます

sum_list_tail :: [Int] -> Int 
sum_list_tail (x:xs) = inc(x:xs, 0) 
    where inc(x:xs, a) = if (x:xs == []) then a else inc(xs, a+x) 

は、それでもまだ意味的なエラーあり:x:xs[]に等しくすることができません。したがって、ifステートメントは常にが偽になります。あなたはをマッチングパターンと協力してこの問題を解決することができます

それでも
sum_list_tail :: [Int] -> Int 
sum_list_tail (x:xs) = inc(x:xs, 0) 
    where inc([], a) = a 
      inc (x:xs, a) = inc(xs, a+x) 

、私にはそれがは非常にハスケルっぽい感じしません。通常は、タプルでは動作しませんが、のような複数の引数、と:sum :: (Num a, Foldable t) => t a -> a

sum_list_tail :: [Int] -> Int 
sum_list_tail ls = inc ls 0 
    where inc []  a = a 
      inc (x:xs) a = inc xs a+x 

さらに定義さsumはすでに存在しています。

あなたがsumを定義したい場合、あなたはまた、インスタンスfoldlのために使用することができます。

sum_list_tail :: (Num b, Foldable t) => t b -> b 
sum_list_tail = foldl (+) 0 
+1

ありがとう、非常に詳細な答え。 –

0

(あなたはfoldrやfoldlのに慣れていない場合)これを解決するために、より自然な再帰はこのようになります:

sum_list_tail :: [Int] -> Int 
sum_list_tail [] = 0 
sum_list_tail (x:xs) = x+ sum_list_tail xs