I'm trying to extract all the largest integers from a list to another list using foldr and a helper function. My understanding of foldr is in conflict with the error messages. Here is my code:
largest :: [Int] -> [Int]
largest [] = []
largest xs = foldr largestHelper [] xs
largestHelper :: [Int] -> Int -> [Int]
largestHelper [] prev = [prev]
largestHelper (lrg : lrgs) prev | lrg < prev = [prev]
| lrg == prev = prev : (lrg : lrgs)
| otherwise = (lrg : lrgs)
To me it looks like the first function to be evaluated is largestHelper
with the last element of the integer list and []
. Next is largestHelper
using the second last element of the list and the previous iteration which is simply the last element because it is the largest this far. And so on. So in the end largest xs
has evaluated to a list which contains one or more integers with the largest value found from the given list.
Here are the errors:
largest.hs:3:20: error:
* Couldn't match type `[Int]' with `Int'
Expected type: [Int] -> [Int] -> [Int]
Actual type: [Int] -> Int -> [Int]
* In the first argument of `foldr', namely `largestHelper'
In the expression: foldr largestHelper [] xs
In an equation for `largest':
largest xs = foldr largestHelper [] xs
|
3 | largest xs = foldr largestHelper [] xs
| ^^^^^^^^^^^^^
largest.hs:3:37: error:
* Couldn't match type `Int' with `[Int]'
Expected type: [[Int]]
Actual type: [Int]
* In the third argument of `foldr', namely `xs'
In the expression: foldr largestHelper [] xs
In an equation for `largest':
largest xs = foldr largestHelper [] xs
|
3 | largest xs = foldr largestHelper [] xs
|
The first one seems to say that largestHelper
is actually receiving two lists of integers instead of the one it is constructing. But doesn't foldr
give elements of the list given to largest
one by one and thus the second argument for largestHelper
would indeed be an integer instead of a list of integers?
The second one seems to say that the argument for largest
is actually [[Int]]
instead of [Int]
. I don't understand that.
I would appreciate very much clarification to this confusion. I don't know yet if this works, because it doesn't compile and as a total beginner in functional programming and Haskell, I would appreciate also comments considering the logic and style of the code.
Your two type errors follow the pattern Couldn't match type `foo' with `bar'
and Couldn't match type `bar' with `foo'
. The problem is you have the wrong argument order for largestHelper
. foldr
calls its function with the element first and the accumulator second, but largestHelper
wants the accumulator first and the element second. Switch the order of them and your type error will be fixed.