Haskell-如果整数大于8,则在列表中创建整数之和

问题描述

我正在尝试创建列表的总和,但仅创建大于8的数字。

sum :: [Int] -> Int
sum[] = 0
sum (x:xs) | x > 8 = x
           | x < 8 = 0
sum (x:xs) = sum xs + x
          


main :: IO ()
main = do
print(sum [1,2,3,4,5,6,7,8,9,10,11,12]) 

所以我希望它加起来9-12并给出42的输出,但是相反它只给出0。 如果我删除了先决条件,则它会正常工作,并对整个列表求和,得出78。 我已经尝试了好几个小时,但仍然无法获得更多的建议,我们将不胜感激。谢谢。

解决方法

您的第二个子句不会递归。因此,这意味着如果x > 8,它将返回x,如果x < 8,它将返回0。仅在x恰好为8的情况下,才会将x加到其余元素的总和上,但是如果第二个元素不是{{1} }。

因此,您需要在8x > 8的两种情况下都要递归:

x <= 8

但是,您不需要为此进行显式递归。您可以使用内置的sum :: (Foldable f,Num a) => f a -> a函数对元素求和,并使用filter :: (a -> Bool) -> [a] -> [a]来过滤元素列表:

sum8 :: [Int] -> Int
sum8 [] = 0
sum8 (x:xs) | x > 8 = x + sum xs
            | otherwise = sum xs

或者我们甚至可以通过以下方式推广该函数以与所有sum8 :: (Num a,Ord a) => [a] -> a sum8 = sum . filter (8 <)类型一起使用:

Foldable

这将因此适用于各种sum8 :: (Foldable f,Num a,Ord a) => f a -> a sum8 = foldr f 0 where f x | x > 8 = (x +) | otherwise = id,例如列表(Foldable),TreesMaybes等。