加载/修改/保存对文本文件的更改

Kie*_*rds 2 haskell functional-programming

请允许我首先分享我目前所拥有的:

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
Run Code Online (Sandbox Code Playgroud)

`

我已经设法加载了一个带有电影类型数据库的 txt 文件,但我无法弄清楚如何实际更改数据。当我尝试运行选项 2 时,我也得到了所有电影的列表以及新添加的电影,但是如果我然后运行选项 1 列出所有电影,它不包括新添加的电影。每次添加新的 Film 实例时,我是否应该将其保存回 txt 文件?非常感谢任何帮助,谢谢!

Dan*_*ner 5

请记住,Haskell 中的一切都是不可变的。当您编写 时addNewFilm (addNewFilm title director (read year) newDb,不会更改由 表示的数据库newDb以包含新信息;它只是返回一个数据库,其中包含所有旧信息和新行。您有责任选择何时何地使用旧数据库(具有讽刺意味的是,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
Run Code Online (Sandbox Code Playgroud)

您可能会注意到这两种情况都以非常相似的模式结束(aputStrLn . displayFilms和 a menu)。统一它们将是一个好主意;看看你是否能自己看到如何做到这一点。

如果您想将修改后的数据库写回文件,您当然需要使用writeFile或类似的函数显式执行此操作。