Reputation: 31
Im trying to take the first and second element of the pair from a list so they can be summed. Here is my code, I am not sure why it is giving an error
func :: [(Double,Double)] -> (Double,Double)
func [(x, y)] = map fst (x,y)
Upvotes: 2
Views: 1604
Reputation: 8477
First, let's take your current, non-working definition:
func :: [(Double,Double)] -> (Double,Double)
func [(x, y)] = map fst (x,y)
This has several things wrong with it:
[(x, y)]
only matches a list with exactly one element. Any list with 2 or more elements will cause an error since they do not match.map
cannot be applied to tuples; it can only be applied to lists.map
over a tuple, fst
must be applied to a tuple directly - fst (a, b)
gives a
, while map fst (a, b)
doesn't make sense.Let's look at some alternate definitions.
func_1 :: [(Double,Double)] -> (Double,Double)
func_1 list =
let fsts = [ a | (a, _) <- list ]
snds = [ b | (_, b) <- list ]
in (sum fsts, sum snds)
This separately extracts each first element from the list, then each second element from the list, then adds them together.
func_2 :: [(Double,Double)] -> (Double,Double)
func_2 list =
let fsts = map fst list
snds = map snd list
in (sum fsts, sum snds)
Maps fst
over each element of the input list to get a list of all first elements of the list. Then maps snd
to do the same for second elements.
func_3 :: [(Double,Double)] -> (Double,Double)
func_3 [] = (0, 0)
func_3 ((a,b) : xs) =
let (a', b') = func_3 xs
in (a+a', b+b')
A bit of a different approach. Lists in Haskell are formed recursively: [a, b, c]
is equivalent to (a : (b : (c : [])))
. This means we can use pattern matching to get the first element of the list as well as all the other elements of the list. This definition works in two parts:
(0, 0)
(the base case).[b, c]
if [a, b, c]
was given, or []
if [a]
was given), calculate its sum using func_3
again, then add the first element back on.Upvotes: 7