In addition to what @jwodder said, note that there's also another way to approach the problem. Instead of thinking /how/ you would compute the desired value, think about /what/ you do: you take the second element of every list item and then sum those elements up.
So you could start by writing two functions, one which takes a list of tuples yielding a list of all the second elements, and another computing the sum of a given list of numbers. A good start is to come up with the type signatures but defining the functions to evaluate to undefined
:
-- Takes a list of tuples and returns all the second elements
getSecondElements :: [(String, Int)] -> [Int]
getSecondElements someList = undefined
-- Computes the sum of a given list of integers
sumOfIntList :: [Int] -> Int
sumOfIntList someInts = undefined
Using these, defining you function is straightforward:
total myList = sumOfIntList (getSecondElements myList)
You can run this through ghci and it'll type-check, which is a good sign. When you try to actually use total
, you get an error though because the other two functions are just undefined
.
Before you go and think about how to implement them, it's a good idea to see whether they exist already. You can search Hoogle for type signatures and it'll dig up functions matching that signature. The signature of getSecondElements
doesn't yield any hits but the signature for the second yields a lot of hits, and most of those hits don't even talk about Int
at all: Hoogle is smart enough to understand that functions which deal on arbitrary types of lists (say: length
or head
) may also be applicable. If you scroll down the page you'll see that there's an existing sum
function already!
For the first function, you can repeat the process (recursively, if you like): in order to get all second-tuple-elements in a list, you first need a function which gets the second element of a tuple, like
getSecondElement :: (String, Int) -> Int
getSecondElement = undefined
and another function which applies that to all elements of a list. I'll skip ahead a bit: the standard function for getting the second element of a 2-tuple is called snd
, and the function for collecting the results of calling a function on all elements of a list is called map
. Try running
:t map snd
in ghci to see the type of map snd
:
map snd :: [(a, b)] -> [b]
...which is a generalized version of the type of our getSecondElements
function! So the two missing pieces are map snd
and sum
, which gives:
-- Takes a list of tuples and returns all the second elements
getSecondElements :: [(String, Int)] -> [Int]
getSecondElements someList = map snd someList
-- Computes the sum of a given list of integers
sumOfIntList :: [Int] -> Int
sumOfIntList someInts = sum
Instead of having two extra functions, you can also define total
in terms of map snd
and sum
directly:
total someList = sum (map snd someList)
...which can be shortened to
total = sum . map snd
Not bad, is it?