返回列表中仅正数的平方和的程序

时间:2014-05-20 20:38:09

标签: haskell

我尝试在Haskell中创建一个程序,通过使用过滤器函数返回列表中只有正数的平方和。

这是我的第一次尝试:

sumsq :: [Int] -> Int
sumsq xs = foldr (+) 0 filter isPositive xs

isPositive :: Int -> Bool
isPositive x | x > 0     = True
             | otherwise = False

但它不起作用,这是我收到的错误消息:

Couldn't match expected type `[(Int -> Bool) -> [Int] -> Int]'
            with actual type `(a0 -> Bool) -> [a0] -> [a0]'
In the third argument of `foldr', namely `filter'
In the expression: foldr (+) 0 filter isPositive xs
In an equation for ` sumsq':
     sumsq xs = foldr (+) 0 filter isPositive xs

溶液: 添加括号后,它正常工作。

    sumsq :: [Int] -> Int
    sumsq xs = foldr (+) 0 (filter isPositive xs)

    isPositive :: Int -> Bool
    isPositive x | x > 0 = True

我的新问题是:为什么它使用括号而不是没有括号?

1 个答案:

答案 0 :(得分:2)

如果没有括号,您说filterisPositivexs都是折叠的参数。这不起作用,因为foldr期望列表作为其第三个参数,而不是两个函数后跟一个列表。你想要的是将调用filter isPositive xs结果作为第三个参数传递给foldr,这就是括号指定的内容。

您可以通过编写foldr (+) 0 $ filter isPositive xs来获得相同的效果,因为$运算符基本上意味着围绕它后面的所有内容包装一组括号。

请注意,您还可以使用函数组合更简洁地编写此函数(无需提及xs)并且无需显式折叠:

sumsq = sum . map (^2) . filter (>0)