Haskell - 向用户显示所有用户的评级

时间:2016-03-04 14:22:20

标签: haskell

你好。以下是我到目前为止的内容:

import Prelude    
import Data.Char
import Data.List
import Text.Printf
import Data.Ord

-- Define Film type here
type Film = (Title,Director,Year,[UserRatings])    

-- Database Type    
type Database = [Film]    

testDatabase :: [Film]    
testDatabase = [
("Blade Runner", "Ridley Scott", 1982, [("Amy",5), ("Bill",8), ("Ian",7), ("Kevin",9), ("Emma",4), ("Sam",7), ("Megan",4)]),    
("The Fly", "David Cronenberg", 1986, [("Megan",4), ("Fred",7), ("Chris",5), ("Ian",0), ("Amy",6)]),    
("Psycho", "Alfred Hitchcock", 1960, [("Bill",4), ("Jo",4), ("Garry",8), ("Kevin",7), ("Olga",8), ("Liz",10), ("Ian",9)]),    
("Body Of Lies", "Ridley Scott", 2008, [("Sam",3), ("Neal",7), ("Kevin",2), ("Chris",5), ("Olga",6)]),    
("Avatar", "James Cameron", 2009, [("Olga",1), ("Wally",8), ("Megan",9), ("Tim",5), ("Zoe",8), ("Emma",3)]),    
("Titanic", "James Cameron", 1997, [("Zoe",7), ("Amy",1), ("Emma",5), ("Heidi",3), ("Jo",8), ("Megan",5), ("Olga",7), ("Tim",10)]),    
("The Martian", "Ridley Scott", 2015, [("Emma",7), ("Sam",8), ("Wally",5), ("Dave",10)])
               ]

getRate :: [UserRatings] -> String -> Int    
getRate [] user = 0 
getRate ((name, rate):xs) user    
    | user==name = rate    
    | otherwise = getRate xs name    
--  Checks if the name of the Tuple is equal to the input String and outputs the rate

printFilmRating :: String -> Film -> String    
printFilmRating user (t,d,y,u) = "Title: " ++ t ++ "\nUser's Rating: " ++ (show (getRate u user)) ++ "\n" ++ "\n"    
--  Formatting the output of Title and the tuple userRatings    

printFilmRate :: String -> Database -> String    
printFilmRate user database = concat (map (printFilmRating user) database)    
--  Applies the printFilmRating funtion to the database and the list is concatenated as String    

checkRate :: [UserRatings] -> String -> Bool    
checkRate [] user = False    
checkRate ((name, rate):xs) user    
    | name == user && rate>0 = True    
    | otherwise = checkRate xs user    
--  Checks if the input String is the same with the userRatings' string and if rate is >0    

checkRating :: String -> Film -> Bool    
checkRating user (_ ,_ ,_ ,u) = checkRate u user    
--  Checks if the input String matches with a film's rating    

----- Main Function -----    
filmsRateByUser :: String -> Database -> String        
filmsRateByUser user database = printFilmRate user (filter (checkRating user) database)        

----- Demo Function -----    
demo :: Int -> IO ()    

demo 1  = putStrLn (filmsRateByUser "Emma" testDatabase)    
-- film titles and user ratings for "Emma"   

*Main> demo 1
Title: Blade Runner
User's Rating: 0

Title: Avatar
User's Rating: 0

Title: Titanic
User's Rating: 0

Title: The Martian
User's Rating: 7

因此,出于某种原因,当我执行“demo 1”函数时,它只计算数据库中Rating的第一个元素。我需要所有的用户费率 如果有人可以帮助而不是更改代码的节奏吗?

1 个答案:

答案 0 :(得分:2)

otherwise = getRate xs name

应该是

otherwise = getRate xs user