Haskell Quiz/Animal Quiz/Solution Jethr0

From HaskellWiki
< Haskell Quiz‎ | Animal Quiz
Revision as of 13:37, 23 December 2006 by JohannesAhlmann (talk | contribs) (Haskell Quiz/Animal Quiz/Solution Animal Quiz moved to Haskell Quiz/Animal Quiz/Solution Jethr0)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
data Question = Question {qString :: String, qYes,qNo :: Question} | Guess String deriving (Show,Eq)

getAnswer :: String -> IO Bool
getAnswer prompt = do putStrLn prompt
                      let loop = do a <- getLine
                                    case a of
                                      "y" -> return True
                                      "n" -> return False
                                      _   -> loop
                      loop                                       

initQuestion = Guess "an elephant"

loopAsk q = do ask' <- ask q
               again <- getAnswer "Play again? (y/n)"
               if again then loopAsk ask' else return ask'

ask :: Question -> IO Question
ask (Guess animal) = do answer <- getAnswer $ "Is it " ++ animal ++ "? (y/n)"
                        if answer then do putStrLn "I win. Pretty smart, aren't I?"
                                          return (Guess animal)
                                  else addEntry animal
ask q@Question{}   = do answer <- getAnswer $ qString q
                        new <- ask $ if answer then qYes q else qNo q
                        return $ if answer then q{qYes = new} else q{qNo = new}

addEntry :: String -> IO Question
addEntry oldAnimal = 
    do putStrLn "You win. Help me learn from my mistake before you go..."
       putStrLn "What animal were you thinking of?"
       animal <- getLine
       putStrLn $ "Give me a question to distinguish " ++ animal ++ " from " ++ oldAnimal
       question <- getLine
       answer <- getAnswer $ "For " ++ animal ++ ", what is the answer to your question? (y/n)"
       putStrLn "Thanks."
       let (y,n) = if answer then (animal, oldAnimal) else (oldAnimal, animal)
       return $ Question {qString = question, qYes = (Guess y), qNo = (Guess n)}