У меня есть задача написать игру Quiz Animal. Мне нужно прочитать данные дерева из файла (структура файла бесплатна). После окончания игры можно добавить новые данные в дерево (на самом деле (Animal), которое должно быть заменено на (Node (Animal) (Animal)).Разбор двоичного дерева из файла в Haskell
Моя проблема в том, что я не могу разобрать содержимое базы данных. .txt»в AnimalsTree
Пример "database.txt"(это содержание генерируется с записью перед вызовом 'New Game'):
Question "Is it fly?" (Animal "Bird") (Question "Is it swim?" (Animal "Fish") (Animal "Dog"))
EDIT Это полный код:
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' [email protected](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' [email protected](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() }
Вы уже получили 'Read'. Разве это не дает вам парсер бесплатно? Или, более того: что вы пытались, что вы ожидали, и что произошло вместо этого? –
Я редактирую свой пост! –
Вы не можете вернуть чистое значение из функции 'main'. Кроме того, 'return' не является« возвратом »на таких языках, как C или Java, это функция из класса типа« Monad », очень мощного инструмента абстракции. – ThreeFx