我正在尝试将Film类型更改为数据类型,以便更容易订购和保存并加载到文件,我在使用正确的参数匹配函数时遇到问题,使用类型更容易.
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
Run Code Online (Sandbox Code Playgroud)
没有太多必然会改变,而不是
filmsByDirector name = filter (\(a,_,_,_) -> a == name) testDatabase
Run Code Online (Sandbox Code Playgroud)
在哪里使用(,,,)
模式的Film
构造函数,您可以使用构造函数
filmsByDirector name = filter (\(Film a _ _ _) -> a == name) testDatabase
Run Code Online (Sandbox Code Playgroud)
和其他功能类似.
但是,使用命名字段(或记录)语法和定义会更方便
data Film = Film { director, title :: String, year :: Int, ratings :: [Rating] }
Run Code Online (Sandbox Code Playgroud)
然后功能就是这么简单
filmsByDirector name = filter ((name ==) . director) testDatabase
Run Code Online (Sandbox Code Playgroud)
或者,如果你对无点风格感到不舒服
filmsByDirector name = filter (\f -> director f == name) testDatabase
Run Code Online (Sandbox Code Playgroud)
关于Film
vs [Film]
in 的错误addFilm
,你必须将最后一部电影包装成[]
,
addFilm title director year db = db ++ [Film title director year []]
Run Code Online (Sandbox Code Playgroud)