Reputation: 1651
Assuming that I have this function:
sales::Int->Int
this function returns the number of sales in a specific week,the weeks are organized as a series 0,1,2.... (it gets the number of week and return the number of sales in that week)
I need to define the function zeroWeeks : zeroWeeks gets an integer n and returns number of weeks that has 0 sales in range [0...n]. (list of weeks)
I have solved it with list comprehension,
this is how I solved it with list comprehension:
zeroWeeks:: Int -> Int
zeroWeeks n = length(ans)
where ans = [w|w<-[0..n],sales w==0]
How can I solve it with foldr function and without using recursion ?
Upvotes: 1
Views: 306
Reputation: 69994
I think its a good idea to look how your function would look like using manual recursion instead of list comprehensions:
zeroWeeks :: [Int] -> Int
zeroWeeks [] = 0
zeroWeeks (x:xs) = (if sales x == 0 then 1 else 0) + zeroWeeks xs
Now, lets look at how foldr
is defined
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
As you can see, foldr is kind a high level pattern for defining functions similar oto zeroWeeks, with z
standing in for the base case and f
standing in for the operation we do in the recursive case. In zeroWeeks's case, its easy to see that we want to make z
to be 0 and the tricky part is finding the f. Basically, what we need to do is make the x
and zeroWeeks xs
as explicit parameters instead of parts of a biggger expression:
zeroWeeks (x:xs) = (\x sum -> (if sales x == 0 then sum + 1 else sum)) x (zeroSum xs)
The end result is thus
zeroSum xs = foldr (\x sum -> (if sales x == 0 then sum + 1 else sum)) 0 xs
Although I would highly recommend refactoring that big lambda function into a separate functions for readability, like Benjamin Kovach did in his answer.
Upvotes: 1
Reputation: 3260
You can define a helper function f
that returns 1 if there were 0 sales for some week, and 0 otherwise. Then you can compose +
and f
to map "zero weeks" to 1 and everything else to 0, then take the sum.
zeroWeeks :: [Int] -> Int
zeroWeeks = foldr ((+) . f) 0
where f w | sales w == 0 = 1
| otherwise = 0
Upvotes: 1