In today’s Programming Praxis exercise, our goal is to write a program that allows children to test their arithmetic skill. Let’s get started, shall we?
First, some imports.
import Control.Monad import System.Random import Text.Printf
All we need for a new sum are two random numbers.
drill :: Maybe Int -> IO () drill n = play n =<< liftM2 (,) rnd rnd where rnd = randomRIO (1, maybe 10 id n)
Processing input isn’t too difficult. Just print the appropriate response and repeat the same sum if the answer is wrong or start a new one when the correct answer is given or requested. Since getLine produces an error when an end-of-file character is encountered we have to use catch to deal with it.
play :: Maybe Int -> (Int, Int) -> IO () play n (a,b) = printf "%d + %d = " a b >> catch getLine (\_ -> return "quit") >>= \s -> case s of "quit" -> putStrLn "Goodbye!" "?" -> print (a + b) >> drill n x -> if x == show (a + b) then putStrLn "Right!" >> drill n else putStrLn "Wrong, try again!" >> play n (a,b)
All that’s left to do is to start the program.
main :: IO () main = drill Nothing