0

Possible Duplicate:
Haskell - Selectively Adding Lists

I have a data type:

data Film = Film String String Int [Rating]
     deriving (Show,Ord,Eq, Read)

A sample film:

("Ridley Scott","Alien",1979,[("Mark",5),("Zoe",3)])

How would I go about getting the average director rating across all films in a list of [Film]?

So if Ridley Scott had 2 films which both individually had an average score of 5 then he would score an overall average of 5.

I only have the code to work out a single Film

filmRating :: [(String,Int)] -> Float
filmRating ratings = average (map snd ratings) 
Community
  • 1
  • 1
JamieB
  • 923
  • 9
  • 30
  • Could you show us the code you tried to write, please? – Riccardo T. May 01 '12 at 13:02
  • I only have the code to work out a single Film filmRating :: [(String,Int)] -> Float filmRating ratings = average (map snd ratings) – JamieB May 01 '12 at 13:06
  • Write a function `Film -> Float` that will return average score of a film (use pattern matching). Then, write a function `[Film] -> Float` that will return average score of list of films (use `average` and previous function). – sdcvvc May 01 '12 at 13:11
  • @sdcvvc: that's not what he wants to achieve. He wants the average score per director :) – Riccardo T. May 01 '12 at 13:12
  • 4
    See this earlier question... http://stackoverflow.com/questions/10210225/haskell-selectively-adding-lists – Don Stewart May 01 '12 at 13:15

1 Answers1

1

Not a real answer, just some newbie notes.

You can use type aliases for Director, Title and all others types.

type Director = String
type Rate = Double
type Rater = String
type Ratings = [(Rater, Rate)]
type Title = String
type Year = Int

data Film = Film Director Director Year Ratings
     deriving (Show,Ord,Eq, Read)

That's why your film example should looks like:

film = Film "Ridley Scott" "Alien" 1979 [("Mark",5),("Zoe",3)]

If you have a function named filmRating it should be something like :: Film -> Rate:

filmRating :: Film -> Rate
filmRating (Film _ _ _ ratings) = average (map snd ratings)

How would I go about getting the average director rating across all films in a list of [Film]?

You want something like directorsAverageRate :: Director -> [Film] -> Rate.

First of all, you need to filter films by Director value with some :: Film -> Director function. For this filtered list you simply get average rate with average . (map filmRating).


UPD:

I don't understand how to get the overall average after I have the films involved.

Let's take the definition of average function from the similar question:

average :: (Real a, Fractional b) => [a] -> b
average xs = realToFrac (sum xs) / genericLength xs

Then

> let one_film = Film "Ridley Scott" "Alien" 1979 [("Mark",5),("Zoe",3)]
one_film :: Film

> let another_film = Film "Ridley Scott" "Alien2" 2979 [("Mark",4),("Zoe",2)]
another_film :: Film

> let films = [one_film, another_film]
films :: [Film]

> average . (map filmRating) $ films
3.5
it :: Double
Community
  • 1
  • 1
  • Yup I understand the filtering but I don't understand how to get the overall average after I have the films involved. – JamieB May 01 '12 at 14:15