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

Haskell 仅返回列表中正数的平方和的程序,haskell,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

我试图用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

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

没有括号,你是说
过滤器
isPositive
xs
都是折叠的参数。这是行不通的,因为
foldr
需要一个列表作为其第三个参数,而不是两个函数后跟一个列表。您需要将调用
过滤器isPositive xs
的结果作为第三个参数传递给
foldr
,这就是括号中指定的

您可以通过编写
foldr(+)0$filter isPositive xs
来获得相同的效果,因为
$
操作符基本上意味着将一组括号括在其后的所有内容上

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

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

提示:
foldr
的第三个参数应该是什么?你目前的第三个论点是什么?你能用括号来解决这个问题吗?它应该是一个列表。如果你回答我评论中的另外两个问题,你就差不多完成了。试着把你的头绕在它周围。最后提示:当前的第三个参数也包含在错误消息中。您当前的第三个参数是列表吗?其他提示:
isPositive x=x>0
,或者只使用
(>0)
进行筛选
sum
也是一个函数。
foldr(+)0 filter isPositive xs
的意思是
foldr(+),0,filter,isPositive,xs)
-也就是说,调用
foldr
,使用参数
(+),0,filter,isPositive,xs
。这显然毫无意义。而
foldr(+)0$filter isPositive xs
表示
foldr(+),0,filter(isPositive,xs))
-使用
isPositive,xs
调用
filter
,然后使用
(+),0
调用
foldr
和上一次计算的结果。