2016-03-04 65 views
1

你好。以下是我迄今为止: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 

所以,出于某种原因,当我执行“演示1”功能,只计算在数据库中的评级的第1个要素。我需要全部的用户费率。
如果有人可以帮助没有改变那个代码的速度很多?

回答

2
otherwise = getRate xs name 

应该是

otherwise = getRate xs user 
+0

可能具有更强的类型更容易地发现错误,例如,'NEWTYPE用户=用户String'。 –

+0

不,它不能。这两个都是'User'类型,然后是 – Alistra

+0

Oop,对吧。出于某种原因,我误解了'name'不是指用户。我猜一个较不容易出错的公式(仍然有明确的递归)会是'getRate user = go where go [] = 0;去((姓名,费率):xs)| name == user = rate |否则=转到xs' –

相关问题