我尝试在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
我的新问题是:为什么它使用括号而不是没有括号?
答案 0 :(得分:2)
如果没有括号,您说filter
,isPositive
和xs
都是折叠的参数。这不起作用,因为foldr
期望列表作为其第三个参数,而不是两个函数后跟一个列表。你想要的是将调用filter isPositive xs
的结果作为第三个参数传递给foldr
,这就是括号指定的内容。
您可以通过编写foldr (+) 0 $ filter isPositive xs
来获得相同的效果,因为$
运算符基本上意味着围绕它后面的所有内容包装一组括号。
请注意,您还可以使用函数组合更简洁地编写此函数(无需提及xs
)并且无需显式折叠:
sumsq = sum . map (^2) . filter (>0)