Search code examples
listhaskellmap-function

How to sum tuples in a list of tuples?


I have the following list for example:

example = [(5.4, 3.2), (2.4, 3.5), (2.4, 4.0), (5.1, 3.6)]

And I'd like to get the sum of each '()' tuple. It means that I'd like to sum 5.4 with 3.2, then 2.4 with 3.5 and so on.

The result should look like this:

First: 8.6
Second: 5.9
Third: 6.4
Fourth: 8.7

I could do it with one pair only, but don't know how to get each sum from the list.

sumexample:: [(Double, Double)] -> [Double]
sumexample [(a, b)] = a + b

Solution

  • So you wrote

    sumexample :: [(Double, Double)] -> [Double]
    sumexample [(a, b)] = [ a + b ]
      --                 ^^^     ^^^     -- (error, corrected)
    

    Ah, great! You've already got all you need to solve it. Almost. The missing part is the appending operator ++, with which a list of any length can be built by appending the singleton lists of its elements:

    [  1,     2,     3,    ...  ] ===
      [1] ++ [2] ++ [3] ++ ...
    

    So then sumexampleList should follow the law of

    sumexampleList :: [(Double, Double)] -> [Double]
    sumexampleList   [a  ,                  b  ,              c  ,  ... ]   ===
    sumexampleList ( [a] ++                [b] ++            [c] ++ ...   ) ===
          sumexample [a] ++ sumexample     [b] ++ sumexample [c] ++ ...     ===
          sumexample [a] ++ sumexampleList [b,                c,    ... ] 
          --                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   --- right?
    

    Haskell doesn't understand the above as a valid definitional syntax though. But it does understand

    [1,   2,  3,  ...] ===
     1 : [2,  3,  ...]
    

    and so we can re-write the above law in the conventional syntax as

    sumexampleList (a : bcde) =
       sumexample a ++ sumexampleList bcde
    

    and that is a bona fide recursive function definition in Haskell. One case is missing though, the one with the empty list, [].

    You will need to complete the definition by adding that additional equation.


    Having solved this, sumexample :: [(Double, Double)] -> [Double] is bad design: it only works with singletons, but the type is list. So do away with the brackets altogether:

    sumexample :: (Double, Double) -> Double
    sumexample (a, b) = ....
    

    and amend the recursive definition accordingly.