简体   繁体   中英

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.

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]
- The 2nd guard adds ["Emma",10] to "Hugo" film

So in the swapRate function, I can't bring both guards to work at the same time. 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).

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 . Fundamentally what you're doing is changing elements of testDatabase , not stripping elements out. 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 ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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