I am trying to change the Film type to a data type so it will make it easier to order and save and load to a file, I am having problems matching the functions up with the right arguments, it was a lot easier working with the types.
type Rating = (String, Int)
--type Film = (String, String, Int, [Rating])
data Film = Film String String Int [Rating]
deriving (Show,Ord,Eq, Read)
testDatabase :: [Film]
testDatabase = []
testFilm = ("Test","Test",2012,[("Test",8),("Test",5)])
saveToFile :: IO ()
saveToFile = do
putStrLn "Enter the output filename: "
name <- getLine
writeFile name (show testDatabase)
putStrLn "Done"
loadFromFile :: IO ()
loadFromFile = do
putStrLn "Enter the input filename: "
name <- getLine
contents <- readFile name
let testDatabase = length contents `seq` (read contents :: [Film])
putStrLn formatDatabase
putStrLn "Done"
average xs = realToFrac (sum xs) / genericLength xs
addFilm :: String -> String -> Int -> [Film] -> [Film]
addFilm title director year db = db ++ Film title director year []
filmsByDirector :: String -> [Film]
filmsByDirector name = filter (\(a,_,_,_) -> a == name) testDatabase
filmsByRating :: Float -> [Film]
filmsByRating rating = filter (\(_,_,_,a) -> filmRating a > rating) testDatabase
filmsByYear :: Int -> [Film]
filmsByYear year = filter (\(_,_,a,_) -> a == year) testDatabase
filmRating :: [(String,Int)] -> Float
filmRating ratings = average (map snd ratings)
formatString :: Film -> String
formatString (dir, film, year, rat) = printf "\n\nDirector: %s \nFilm Name: %s \nYear: %s \nRating: %4.2f" (show dir) (show film) (show year) (filmRating rat)
formattedByYear :: Int -> String
formattedByYear year = concatMap formatString $ filmsByYear year
formattedByDirector :: String -> String
formattedByDirector dir = concatMap formatString $ filmsByDirector dir
formatDatabase = concatMap formatString $ testDatabase
There isn’t much to necessarily change, instead of
where you use the
(,,,)constructor for the pattern, you use theFilmconstructorand similarly for the other functions.
However, it’s much more convenient to use named-field (or record) syntax and define
and then the function would be simply
or, if you’re uncomfortable with point-free style
For the error regarding
Filmvs[Film]inaddFilm, you have to wrap the last film into[],