Jubl
Jubl

Reputation: 247

List Average for Ints

I'm new to Haskell and Stackoverflow and I'm trying to teach myself Haskell programming and I'm doing a series of exercises from a book I downloaded and was wondering if you guys could help me out here.

I'm trying to write a function called avgPub which returns the average of all the years of publication for a series of books. The function arguments are: avgPub :: [(String, String, Int)] -> Int. An example of input/output is,

> avgPub [("publisher", "book", 1920), ("publisher1", "book1", 1989), ("publisher2", "book2", 1920)]
1943

Yesterday, I learned about div, sum, and map, but I'm not sure how to tie it all together for this problem (as the exercise is hinting at). I think that to find the average of a list of Ints, you do list (x:xs) = (sum (x:xs))divlength, but we are dealing with more than just Ints so this won't work.

I'm having trouble figuring out how to tie it all together.

Upvotes: 4

Views: 2059

Answers (3)

nemetroid
nemetroid

Reputation: 2159

You're on the right track with year' :: [(String, String, Int)] -> Int. You want to somehow extract the year field from all the records to be able to average them.

The easiest way to do this is to write a function that takes a single record and extracts the year. I.e. like this:

year :: (String, String, Int) -> Int
year (_, _, i) = i

(note that the first argument is not a list)

Then you can make another function, years, to get a list of Ints from a list of records:

years :: [(String, String, Int)] -> [Int]
years xs = map year xs

Then all you need to do is to put this together with code for calculating the average of a list of Ints:

average :: [Int] -> Int
average xs = (sum xs) `div` (length xs)

To tie it together:

avgPub books = average (years books)

Upvotes: 2

Ingo
Ingo

Reputation: 36339

For the "tying it all together" part, as a beginner, you can write code in the following style:

avgPub books = result where
    result = average yearlist
    yearlist = map year' books

After a while, you'll shorten this to

avgPub = average . map year'

Upvotes: 0

Syd Kerckhove
Syd Kerckhove

Reputation: 833

Hint:

year' :: [(String, String, Int)] -> [Int]
year' = map (\(_,_,i) -> i)

Oh, and if you find something that works, put it up on https://codereview.stackexchange.com/ , as you say you're new to Haskell.

Upvotes: 0

Related Questions