Haskell输入数据

Haskell输入数据,haskell,Haskell,我正在尝试将胶片类型更改为数据类型,这样可以更容易地排序、保存和加载到文件中,我遇到了将函数与正确参数匹配的问题,使用类型更容易 type Rating = (String, Int) --type Film = (String, String, Int, [Rating]) data Film = Film String String Int [Rating] deriving (Show,Ord,Eq, Read) testDatabase :: [Film] testD

我正在尝试将胶片类型更改为数据类型,这样可以更容易地排序、保存和加载到文件中,我遇到了将函数与正确参数匹配的问题,使用类型更容易

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

没有什么需要改变的,而是

filmsByDirector name = filter (\(a,_,_,_) -> a == name) testDatabase
当你对图案使用,,,构造器时,你使用胶片构造器

filmsByDirector name = filter (\(Film a _ _ _) -> a == name) testDatabase
对于其他函数也是如此

但是,使用命名字段或记录语法并定义

data Film = Film { director, title :: String, year :: Int, ratings :: [Rating] }
然后函数就简单了

filmsByDirector name = filter ((name ==) . director) testDatabase
或者,如果你不喜欢无点风格

filmsByDirector name = filter (\f -> director f == name) testDatabase
对于addFilm中有关Film vs[Film]的错误,您必须将最后一部影片包装到[]


Film是代码中的数据类型,您必须提供更多详细信息。另外,您可能对文件感兴趣。hs:43:40:无法在+++的第二个参数中调用Film的返回类型中,将预期类型[Film]'与实际类型Film'匹配,即表达式中的'Film title director year[]'中的'Film title director year[]谢谢!我将如何接收胶片作为变量?以前我可以将电影分成不同的变量,我需要做电影->字符串->字符串->整型->分级->字符串吗?我不确定我是否理解。如果您想使用记录语法获取例如标题第二个字符串,那么您已经有了选择器title::Film->String。如果没有录制语法,它将是标题电影,就像元组一样,它是标题,t,t,t。对不起,我不够清楚。formatString dir film year rat=printf\n\n目录:%s\n文件名:%s\n目录:%s\n日期:%4.2f show dir show film show year film rating rating rat我无法以与以前相同的方式直接访问dir/film/year或rat,这就是我询问是否需要更改正式参数的原因。已解决:formatString::Film->String formatString Film dir Film year rat=printf\n\n目录:%s\n电影名称:%s\nYear:%s\n分级:%4.2f show dir show Film show year Film rat例如。但我建议不要使用show year,而是在printf格式字符串中使用%d格式。
addFilm title director year db = db ++ [Film title director year []]