I tried to make a program in Haskell that returns the sum of squares of only the positive numbers in a list by using the filter function.
this is my first attempt:
sumsq :: [Int] -> Int
sumsq xs = foldr (+) 0 filter isPositive xs
isPositive :: Int -> Bool
isPositive x | x > 0 = True
| otherwise = False
but it's not working and this is the error message I am getting :
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
solution: after adding parentheses it's working correctly.
sumsq :: [Int] -> Int
sumsq xs = foldr (+) 0 (filter isPositive xs)
isPositive :: Int -> Bool
isPositive x | x > 0 = True
my new question is: why is it working with the parentheses and not without the parentheses ?
Without the parentheses, you're saying that filter
, isPositive
, and xs
are all arguments to the fold. That doesn't work because foldr
expects a list as its third argument, not two functions followed by a list. What you want is to pass the result of calling filter isPositive xs
as the third argument to foldr
, and that's what the parentheses specify.
You can get the same effect by writing foldr (+) 0 $ filter isPositive xs
, since the $
operator basically means to wrap a set of parentheses around everything that follows it.
Note that you can also write this function more concisely in point-free form (no need to mention xs
) and without an explicit fold, using function composition:
sumsq = sum . map (^2) . filter (>0)
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments