0

I need to recurse through two lists in a function and I can't see a way to do it.

siteRating6OrHigher :: [Film] -> [String]
siteRating6OrHigher [] = []
siteRating6OrHigher ((Film title _ _ ((_, rating):ratings)):restOfFilms)
    | rating >= 6 = [title] ++ siteRating6OrHigher restOfFilms
    | otherwise = siteRating6OrHigher restOfFilms

My data is formatted: testDatabase = [Film "Blade Runner" "Ridley Scott" 1982 [("Amy",6), ("Bill",9), ("Ian",7), ("Kevin",9), ("Emma",4), ("Sam",5), ("Megan",4)], etc

So currently I am recursing through the 'restOfFilms' but i also need to recurse through the list of ratings that are in the Film type. Is there a way to do this so it recurses through each set of ratings for each film?

Thanks

data structure:

data Film = Film String String Int [(String, Int)]
        deriving (Eq,Ord,Show,Read)
3
  • Can you provide the data structures you're working with so the example is self-contained? Commented Feb 24, 2014 at 18:12
  • What do you want to do with the ratings? Commented Feb 24, 2014 at 18:18
  • check if any rating in the list of ratings for a film is above six. My current method only checks the first one in the list Commented Feb 24, 2014 at 18:20

1 Answer 1

3

I would fmap over the list, converting any ratings > 6 into boolean True, then use foldr to go through the list with (||) and default value False, which should reduce the list to a single True if any are above 6 and False otherwise.

foldr (||) False (fmap ((> 6) . snd) ratings)

EDIT: Simpler, as per Rhymoid's suggestion

EDIT 2: The whole solution.

siteRating6OrHigher :: [Film] -> [String]
siteRating6OrHigher [] = []
siteRating6OrHigher ((Film title _ _ ratings):restOfFilms)
    | above60 ratings = [title] ++ siteRating6OrHigher restOfFilms
    | otherwise = siteRating6OrHigher restOfFilms
  where above60 = any ((> 6) . snd)
Sign up to request clarification or add additional context in comments.

6 Comments

Note that any p = foldr (||) False . map p is provided by the Prelude: you can just use any (> 6) instead.
That compiles fine but is still only returning the films that have a rating of greater than 6 in the first one, it doesnt seem to be recursing the other ones
is it possible to do the any .. as a list comprehension
@user3347868 You could do any [r > 6 | (_, r) <- ratings], but I wouldn't say it's more readable than any ((> 6) . snd)
@bheklilr tried siteRating6OrHigher :: [Film] -> [String] siteRating6OrHigher [] = [] siteRating6OrHigher ((Film title _ _ ratings):restOfFilms) | (any [rating >= 6 | (_, rating) <- ratings ]) == True = [title] ++ siteRating6OrHigher restOfFilms | otherwise = siteRating6OrHigher restOfFilms but it doesnt work
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.