I wanted to define the function:
accumulate_list' :: Num a => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f
| [] f = 0
| (x:xs) f = f x (accumulate_list xs f)
but it doesn't compile, complaining that x, xs, x, xs, are Not in scope.
Trying to achieve the same result, I have defined this function
accumulate_list :: Num a => [a] -> ( a -> a -> a ) -> a
accumulate_list [] f = 0
accumulate_list (x:xs) f = f x $ accumulate_list xs f
it compiles well, and does like sum
does on a list if the functgion passed in parameter is (+)
. Yes, I finally found that indeed what I wanted to achieve was already existing in Prelude as the sum
function.
However, I don't understand why the first version with mixed guards and pattern matching doesn't compile. What is the problem ?
It is because guards are basically a boolean expression. They have to evaluate to either True
or False
. Something like this should typecheck:
accumulate_list' :: (Eq a, Num a) => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f
| l == [] = 0
| otherwise = undefined -- fill out undefined
It's also worth mentioning that since pattern guards were added to Haskell 2010, you're allowed to mix patterns and guards like so:
accumulate_list' :: (Eq a, Num a) => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f
| [] <- l = 0 --pattern for the empty list case
| 10 < 5 = 10 --arbitrary regular guard just because
| (x:xs) <- l = undefined --pattern for the non-empty case
Using what @Sibi's answer provided, I've completed it so as to provide entire working code example:
accumulate_list' :: (Eq a ,Num a) => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f
| l == [] = 0
| otherwise = f x $ accumulate_list xs f
where (x:xs) = l
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With