请允许我先分享我到目前为止所拥有的内容:
main :: IO ()
main = do contents <- readFile "filmList.txt"
let database = (read contents :: [Film])
putStr "Please enter your username: "
userName <- getLine
menu database
where menu newDb = do putStrLn "\nPlease select an option:"
putStrLn "1: Display all films currently in the database"
putStrLn "2: Add a new film to the database (and display all films)"
putStrLn "3: "
putStrLn "4: Save Database"
putStrLn "5: Exit"
putStr "\nSelected option: "
option <- getLine
case option of "1" -> putStrLn(displayFilms newDb)
"2" -> do putStr "Name of film: "
title <- getLine
putStr "Name of director: "
director <- getLine
putStr "Year of release: "
year <- getLine
putStrLn(displayFilms (addNewFilm title director (read year) newDb))
menu newDb
我已经设法加载了一个带有电影类型数据库的txt文件,但我无法弄清楚如何实际更改数据。当我尝试运行选项2时,我得到了所有新电影的列表,但如果我然后运行选项1列出所有电影,则不包括新添加的电影。每次添加新的Film实例时,我是否应该保存回txt文件?非常感谢任何帮助,谢谢!
答案 0 :(得分:4)
请记住,Haskell中的所有内容都是不可变的。当您编写addNewFilm (addNewFilm title director (read year) newDb
时,更改由newDb
表示的数据库以包含新信息;它只返回一个 new 数据库,该数据库包含所有旧信息和新行。您有责任选择在何时何地使用旧数据库(具有讽刺意味的是,newDb
)或该函数返回的新数据库。
例如,您可以改为编写此case
:
case option of "1" -> putStrLn (displayFilms newDb) >> menu newDb
"2" -> do ...
let evenMoreReallyNewDb = addNewFilm title director (read year) newDb
putStrLn (displayFilms evenMoreReallyNewDb)
menu evenMoreReallyNewDb
您可能会注意到两种情况都以非常相似的模式结束(putStrLn . displayFilms
然后是menu
)。统一他们将是一个好主意;看看你是否能看到自己如何做到这一点。
如果要将修改后的数据库写回文件,您当然需要使用writeFile
或类似函数明确地执行此操作。