首页 > 解决方案 > 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。我一直在尝试几个小时,仍然无法比这更进一步,任何建议将不胜感激。谢谢你。

标签: haskellfold

解决方案


您的第二个子句不递归。因此,这意味着如果x > 8,它将返回x,如果x < 8,它将返回0。只有在 case xis正是的情况下8,它才会添加x到剩余元素的总和中,但是如果第二个元素不是 ,这个总和也很容易终止8

x > 8因此,您需要在或的两种情况下递归x <= 8

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

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

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

因此,这将适用于各种Foldables,如列表 ( [])、TreesMaybes等。


推荐阅读