我有编写Quiz Animal游戏的任务。我必须从文件中读取树数据(文件的结构是免费的)。游戏结束后可以在树中添加新数据(实际上(动物)将被替换为(Node(Animal)(Animal))。
我的问题是我无法解析AnimalsTree中的“database.txt”内容
示例“database.txt”(此内容是在调用“新游戏”之前通过写入生成的):
问题“飞吗?” (动物“鸟”)(问题“游泳吗?”(动物“鱼”)(动物“狗”))
修改 这是完整的代码:
module Main where
import System.IO
data AnimalsTree = Animal String | Question String AnimalsTree AnimalsTree deriving (Read, Show)
-- Видовете отговори на потребителя
data Answer = Yes | No
main :: IO ()
main = do root <- "database.txt"
play (read root)
return ()
play :: AnimalsTree -> IO AnimalsTree
play root = do putStrLn "Think of an animal, I will try to guess what it is..."
newRoot <- play' root
writeFile "database.txt" (show newRoot)
playAgain <- ask "Do you want to play again?"
case playAgain of
Yes -> play newRoot
No -> do putStrLn "Bye!"
return newRoot
play' :: AnimalsTree -> IO AnimalsTree
play' question@(Question q l r) = do ans <- ask q
case ans of
Yes -> do y <- play' l
return $ Question q y r
No -> do n <- play' r
return $ Question q l n
play' animal@(Animal _) = do ans <- ask $ "Are you thinking of " ++ show' animal ++ "?"
case ans of
Yes -> do putStrLn "I win! :)"
return animal
No -> do putStrLn "I give up, you win!"
getNewAnimal animal
getNewAnimal :: AnimalsTree -> IO AnimalsTree
getNewAnimal animal = do putStrLn "Please help me!"
putStrLn "What is name of yout animal?"
name <- getLine
let newAnimal = Animal name
putStrLn $ "Now please enter a question that answers yes for " ++ show' newAnimal ++ " and no for " ++ show' animal
question <- getLine
return $ Question question newAnimal animal
ask :: String -> IO Answer
ask s = do putStrLn $ s ++ " (Yes/No)"
getAnswer
getAnswer :: IO Answer
getAnswer = do ans <- getLine
putStrLn ""
case ans of
"y" -> return Yes
"Y" -> return Yes
"yes" -> return Yes
"Yes" -> return Yes
"n" -> return No
"N" -> return No
"no" -> return No
"No" -> return No
_ -> putStrLn "This is incorect answer! Please try again with value in 'Yes' or 'No'!" >> getAnswer
show' (Animal name) = (if elem (head name) "AEIOUaeiou" then "an " else "a ") ++ name
show' (Question q _ _) = q
但我得到以下错误:
test3.hs:10:19:
No instance for (Read (IO AnimalsTree))
arising from a use of ‘read’
In a stmt of a 'do' block: root <- read "database.txt"
In the expression:
do { root <- read "database.txt";
play (root);
return () }
In an equation for ‘main’:
main
= do { root <- read "database.txt";
play (root);
return () }
答案 0 :(得分:2)
这看起来是一个很好的开始!我只需要将readFile
添加到您的main
函数中以使其编译:
main = do root <- readFile "database.txt"
您可能需要从readFile
切换到显式打开文件以进行读取,读取和关闭文件。这是因为readFile
无法保证何时关闭文件,如果为writeFile
提供了已经打开的文件的路径,则允许openFile
失败。
您可以阅读hGetLine
,hClose
和hGetContents
的文档,了解有关如何执行此操作的详细信息(但请注意readFile
,因为它有相同的注意事项{{1}}确实如此。