3t893w
3t893w

Reputation: 297

Haskell: add the second elements of 2 tuples if their first elements are equal, in a list of tuples?

Examples:

addElement (1, 1) [(1, 1)] = [(1,2)]

addElement (2, 2) [(1,1),(2, 2)] = [(1,1),(2, 4)]

My code:

addElement :: (Integer, Integer) -> [(Integer, Integer)]  -> [(Integer, Integer)] 
addElement (a,b) ((x,y):xs)
                         | a==x = ((x,y+b):xs) 
                         |otherwise = addElement ((a+1), b)  xs

I couldn't make it work for the rest of the list.

Upvotes: 0

Views: 317

Answers (2)

Chris
Chris

Reputation: 36451

One might also use a list comprehension to accomplish this:

addElem :: (Eq a, Num b) => (a, b) -> [(a, b)] -> [(a, b)]
addElem (x1, x2) lst = [if x1 == y1 then (y1, x2 + y2) else y | y@(y1, y2) <- lst]

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476547

You need to recurse on the function, and for the otherwise case yield the (x,y) 2-tuple. Furthermore you should implement the case with an empty list:

addElement :: (Eq a, Num b) => (a, b) -> [(a, b)]  -> [(a, b)]
addElement _ [] = []
addElement kv@(k1, v1) (kv2@(k2, v2):xs)
    | k1 == k2 = ((k2, v1+v2) : addElement kv xs
    | otherwise = kv2 : addElement kv xs

You can work with map to only implement logic that works on a single element, so:

addElement :: (Eq a, Num b) => (a, b) -> [(a, b)] -> [(a, b)]
addElement (k, v) = map f
    where f kv2@(k2, v2)
              | k == k2 = (k2, v+v2)
              | otherwise = kv2

Upvotes: 2

Related Questions