[英]Haskell - Rate or Rerate a film in a Database
My coding is robust but for some reason at swapRate
function, it needs some fixing to bring the correct results. 我的编码是健壮的,但是由于
swapRate
函数的某种原因,它需要进行一些修复才能带来正确的结果。
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
What's to do: 怎么做:
- The 1st guard overwrites in "Avatar" film the rate of ["Emma",3] to ["Emma",10] -第一卫兵在“阿凡达”电影中覆盖从[“ Emma”,3]到[“ Emma”,10]的比率
- The 2nd guard adds ["Emma",10] to "Hugo" film -第二名后卫在“雨果”电影中添加了[“ Emma”,10]
So in the swapRate
function, I can't bring both guards to work at the same time. 因此,在
swapRate
函数中,我无法同时使用两个防护。 If I comment the first guard, the second one works and vice versa. 如果我评论第一个后卫,第二个后卫会起作用,反之亦然。 Looking for a way to make both work.
寻找一种使两者同时起作用的方法。
To get rid of the warnings, changing your pattern matches on the empty string ""
to just _
does the trick for both checkRateRerate
and swapRate
(which also warns on my machine). 为了消除警告,将空字符串
""
上的模式匹配项更改为_
可以同时满足checkRateRerate
和swapRate
(在我的机器上也会发出警告)的问题。
Your specific problem is that the case you were missing is "What happens if the list is empty, but the strings are not all the empty string?" 您的特定问题是缺少的情况是“如果列表为空,但是字符串不是全部为空字符串,会发生什么?” Both of those functions would fail out in that case.
在这种情况下,这两个功能都将失败。 It seems to be the case that really you just care about handling what happens when the list is empty.
似乎确实是您真正在乎处理列表为空时发生的情况。
As for what to do about your outputs, I would suggest that you use a map
instead of a filter
. 至于如何处理输出,我建议您使用
map
而不是filter
。 Fundamentally what you're doing is changing elements of testDatabase
, not stripping elements out. 从根本上讲,您正在做的是更改
testDatabase
元素,而不是剥离元素。 To do so you'll have to change checkRateRerating
to output a Film
not a Bool
(and perhaps change checkRateRerate
to output [UserRatings]
not a Bool
). 为此,您必须将
checkRateRerating
更改为输出Film
而不是Bool
(也许将checkRateRerate
更改为输出[UserRatings]
而不是Bool
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.