2016-03-06 67 views
0

我的编码非常健壮,但由于某种原因在swapRate函数中,它需要一些修复才能产生正确的结果。Haskell - 在数据库中对影片进行评分或重制

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

-- Types 
type Title = String 
type Director = String 
type Year = Int 
type UserRatings = (String,Int) 

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

-- Database Type 
type Database = [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)]), 
("Hugo", "Martin Scorsese", 2011, [("Sam",9), ("Wally",3), ("Zoe",5), ("Liz",7)]) 
       ] 

swapRate :: String -> Int -> String -> Title -> [UserRatings] -> [UserRatings] 
swapRate _ _ _ _ [] = [] 
swapRate user newRate film title ((name, rate):xs) 
    | user==name && film==title = (user,newRate):xs -- Does demo 11 
    -- | user/=name && film==title = (user,newRate):xs -- Does demo 1 
    | otherwise = (name,rate) : (swapRate user newRate film title xs) 
-- * Outputs an updated list 

printSwappedFilmRating :: String -> Int -> String -> Film -> String 
printSwappedFilmRating user newRate film (t,d,y,u) = "Title: " ++ t ++ "\nDirector: " ++ d ++ "\nYear: " ++ show y ++ "\nUser's Rating: " ++ (show (swapRate user newRate film t u)) ++ "\n" ++ "\n" 
-- * Formatting the output of Title, Director, Year and the tuple UserRatings 

printSwappedFilmRate :: String -> Int -> String -> Database -> String 
printSwappedFilmRate user newRate film database = concat (map (printSwappedFilmRating user newRate film) database) 
-- * Applies the printSwappedFilmRating funtion to the database and the list is concatenated as String 


----- Main Function ----- 

rateOrRerate :: String -> Int -> String -> Database -> String 
rateOrRerate user newRate film database = printSwappedFilmRate user newRate film database 

-- * Receives two Strings and an Int and with the use of printSwappedFilmRate, 
-- it prints all the movies and the updated rating of a particular user with nice formatting  


----- DEMO FUNCTIONS ----- 
demo :: Int -> IO() 

----- Demo 1 ----- 
demo 1 = putStrLn (rateOrRerate "Emma" 10 "Hugo" testDatabase) 
-- * All films after Emma rates "Hugo" 10 

----- Demo 11 ----- 
demo 11 = putStrLn (rateOrRerate "Emma" 10 "Avatar" testDatabase) 
-- * All films after Emma rates "Avatar" 10 

怎样做:
- 第一届后卫 “阿凡达” 的电影改写的速率 “艾玛”,3]至[ “艾玛”,10]
- 第二届后卫补充道[”艾玛“,10]到”雨果“电影

所以在swapRate函数,我不能同时使两个警卫工作。如果我评论第一名后卫,第二名后卫则适用,反之亦然。寻找一种方法,使工作。

+0

'checkRateRerate'不处理所有情况。例如,如果第四个参数('[UserRating]')是一个空列表,但user不是一个空字符串? – kes

+0

我对编码做了一些更正,但需要一些帮助来解决swapRate的情况,以便演示1和11都可以工作。如果你能帮忙,那会很好。谢谢你的时间。 – mirage206wrc

回答

1

为了摆脱的警告,改变你的图案空字符串匹配""只是_的伎俩两个checkRateRerateswapRate(这也提醒我的机器上)。

您的具体问题是您缺少的情况是“如果列表为空,但字符串不全是空字符串,会发生什么?”在这种情况下,这两种功能都会失效。看起来就是这样的情况,你真的只关心处理列表为空时发生的情况。

至于如何处理您的输出,我建议您使用map而不是filter。基本上你正在做的是改变testDatabase的元素,而不是去除元素。要做到这一点,你必须改变checkRateRerating输出Film而不是Bool(也许更改checkRateRerate输出[UserRatings]而不是Bool)。

+0

我对上面的代码进行了更正,并根据您的建议对其进行了更新。但仍然有swapRate功能的问题。如果你有任何线索,那就太棒了。谢谢你的时间。 – mirage206wrc

+0

有几种解决方法。最干净的可能是使用另一种数据结构(如'Data.Map')。或者,你可以创建一个新的函数来搜索给定的用户是否已经存在于用户评级列表中,并且如果是这种情况,可以删除(比如'filter')。然后添加您的新评级。这将有效更新任何旧评级。 – badcook

相关问题