Reputation: 753
I have a list of type Film, where Film(Director Title Year Likes Dislikes), which corresponds to Film -> String -> String -> Int -> [String] -> [String]. I also have a function that takes in the likes and dislikes lists and returns a percentage rating, as such that:
rating :: Likes -> Dislikes -> Int
rating likes dislikes = (((length [likes]) / ((length [dislikes]) + (length [likes]))) * 100)
My problem:
I cannot work out how to use filter
to sort this list, to determine whether or not each film's rating is 75% or over.
This is my current attempt:
filterFilm :: Film -> Bool
filterFilm (Film t d y likes dislikes)
| (rating likes dislikes) > 74 = True
| otherwise = False
-- List film rating with and over 75%
listRating :: Database -> Database
listRating (x:xs) = filter (filterFilm x) (x:xs)
I get this error:
Cw 2018.hs:87:29: error:
• Couldn't match expected type ‘Film -> Bool’
with actual type ‘Bool’
• Possible cause: ‘filterFilm’ is applied to too many arguments
In the first argument of ‘filter’, namely ‘(filterFilm x)’
In the expression: filter (filterFilm x) (x : xs)
In an equation for ‘listRating’:
listRating (x : xs) = filter (filterFilm x) (x : xs)
|
87 | listRating (x:xs) = filter (filterFilm x) (x:xs) |
Any suggestions? Thanks in advance!
Upvotes: 1
Views: 1044
Reputation: 476503
I think you use filter
the wrong way. filter
is a function that takes two parameters, the first one a predicate a -> Bool
and the second one a list of a
s.
Now the parameter that is passed to listRating
is that list, so listRating l
, and you thus call the filter
with filter filterFilm l
, so:
listRating :: Database -> Database
listRating l = filter filterFilm l
We can also remove the l
parameter both in the head and body of the function, like:
listRating :: Database -> Database
listRating = filter filterFilm
Note that you can simplify your filterFilm
function to:
filterFilm :: Film -> Bool
filterFilm (Film t d y likes dislikes) = rating likes dislikes > 74
Upvotes: 2