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.