import Text.Show import Control.Monad import Data.Foldable import Language.Haskell.Interpreter data Expr a = Lit a | Add (Expr a) (Expr a) | Mult (Expr a) (Expr a) instance Show a => Show (Expr a) where showsPrec _ (Lit a) = shows a showsPrec p (Add e1 e2) = showParen (p > precAdd) $ showsPrec precAdd e1 . showString "+" . showsPrec precAdd e2 where precAdd = 5 showsPrec p (Mult e1 e2) = showParen (p > precMult) $ showsPrec precMult e1 . showString "*" . showsPrec precMult e2 where precMult = 6 myeval :: Num a => Expr a -> a myeval (Lit e) = e myeval (Add e1 e2) = myeval e1 + myeval e2 myeval (Mult e1 e2) = myeval e1 * myeval e2 testexpr e = do let e_str = show e e_val = myeval e putStr $ e_str ++ " = " ++ show e_val ++ " " r <- runInterpreter $ setImports ["Prelude"] >> eval e_str case r of Right r' -> if read r' == e_val then putStrLn "ok" else putStrLn "eval error" _ -> putStrLn "interpreter error" main = traverse_ testexpr exprs exprs = [ Mult (Add (Lit 2) (Mult (Lit 3) (Lit 3))) (Lit 5), Add (Add (Lit 1) (Mult (Add (Lit 1) (Lit 2)) (Add (Lit 2) (Mult (Lit 2) (Add (Lit 1) (Lit 2)))))) (Add (Lit 1) (Mult (Lit 3) (Lit 2))), Add (Add (Add (Lit 1) (Lit 2)) (Add (Lit 1) (Lit 2))) (Add (Add (Lit 1) (Lit 2)) (Add (Lit 1) (Lit 2))), Mult (Mult (Mult (Lit 1) (Lit 2)) (Mult (Lit 1) (Lit 2))) (Mult (Mult (Lit 1) (Lit 2)) (Mult (Lit 1) (Lit 2))), Add (Mult (Lit 1) (Mult (Add (Lit 1) (Lit 2)) (Mult (Lit 2) (Add (Lit 2) (Mult (Lit 1) (Lit 2)))))) (Add (Lit 1) (Add (Lit 3) (Lit 2))) ]