import Test.QuickCheck ----------------------------------------------------------------------- data Expr = Num Integer | Add Expr Expr | Mul Expr Expr deriving ( Eq ) eval :: Expr -> Integer eval (Num n) = n eval (Add a b) = eval a + eval b eval (Mul a b) = eval a * eval b ----------------------------------------------------------------------- showExpr :: Expr -> String showExpr (Num n) = show n showExpr (Add a b) = showExpr a ++ "+" ++ showExpr b showExpr (Mul a b) = showFactor a ++ "*" ++ showFactor b showFactor :: Expr -> String showFactor (Add a b) = "(" ++ showExpr (Add a b) ++ ")" showFactor e = showExpr e instance Show Expr where show = showExpr ----------------------------------------------------------------------- instance Arbitrary Expr where arbitrary = arbExpr 5 -- arbExpr :: Gen Expr -- arbExpr = -- oneof [ do n <- arbitrary -- return (Num n) -- , do a <- arbExpr -- b <- arbExpr -- return (Add a b) -- , do a <- arbExpr -- b <- arbExpr -- return (Mul a b) -- ] arbExpr :: Int -> Gen Expr arbExpr s = frequency [ (1, do n <- arbitrary return (Num n)) , (s, do a <- arbExpr s' b <- arbExpr s' return (Add a b)) , (s, do a <- arbExpr s' b <- arbExpr s' return (Mul a b)) ] where s' = s `div` 2 ----------------------------------------------------------------------- questions :: IO ( ) questions = do e <- generate arbitrary putStr ("What is " ++ show e ++ "? ") ans <- getLine putStrLn \$ if read ans == eval e -- show (eval e) == ans then "Right!" else "Wrong!" questions -----------------------------------------------------------------------