Haskell 仅返回列表中正数的平方和的程序
我试图用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
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
和上一次计算的结果。