I have a value sheet of type (x, y) and I would like to get an x sheet, but something goes wrong, here is the code:
x_list:: [(Double, Double)] -> [Double]
x_list list = Prelude.foldl(\t xl -> (fst t):xl) list []
I get this error:
• Couldn't match expected type: (Double, b0)
with actual type: [Double]
• In the first argument of ‘fst’, namely ‘t’
In the first argument of ‘(:)’, namely ‘(fst t)’
In the expression: (fst t) : xl
>Solution :
There are a couple of problems in your code, both related to argument order:
foldl, like all the other folds, takes the argument list as its last (3rd) argument and the starting accumulator (your []) as the one before that – so you need to switch over the list and [] in your definition.
Similarly, the fold function itself has type b -> a -> b – that is it takes the old accumulator as its first element and the element of the list you’re folding as its second. So in your case the first argument is a list of doubles and the second is a pair of doubles (not a list) – your implementation and variable names clearly imply you thought it was the other way round, but the compiler can’t accept this.
(Note that for a right fold the argument order is reversed. This can be confusing – I always remember it by mentally placing the current accumulator at one end of the list: the left end for a left fold and the right end for a right fold, and then noting the fold function consumes its arguments in left-to-right order. Don’t worry if this isn’t helpful for you – I’ve probably explained it badly anyway. It’s not essential, but it helps me!)
So your function when fixed in the above 2 ways will look like this:
x_list:: [(Double, Double)] -> [Double]
x_list list = Prelude.foldl(\xl t -> (fst t):xl) [] list
Note finally that this is much more simply and readably expressed with the map function – which (as you are doing here) applies a function to every element of a list. In this case the simplest definition would be
x_list list = map fst list
or, by "eta reduction", just:
x_list = map fst