简体   繁体   English

Haskell-对数据库中的电影进行评级或评级

[英]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). 为了消除警告,将空字符串""上的模式匹配项更改为_可以同时满足checkRateRerateswapRate (在我的机器上也会发出警告)的问题。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM