Haskell Quiz/Animal Quiz/Solution Jethr0

From HaskellWiki
< Haskell Quiz‎ | Animal Quiz
Revision as of 10:42, 13 January 2007 by Quale (talk | contribs) (sharpen cat)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
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)}