尾递归解析错误 Haskell

Parsing error on tail recursion 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

找不到我做错了什么。

语法错误,是因为where子句中的空格不相等:if语句比[=15]语句的空格少=] 行。因此,您可以通过在 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 )

尽管如此,对我来说不是感觉非常Haskell-ish。通常你不使用元组,而是使用多个参数,比如:

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 :: (Num a, Foldable t) => t a -> a.

如果你想定义一个sum,你也可以使用例如foldl:

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

解决这个问题的更自然的递归(如果您不熟悉 foldr 或 foldl)是这样的:

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