data Term = Con Int | Div Term Term deriving (Show); type M a = (Output, a); type Output = String; answer, err :: Term; answer = (Div (Div (Con 1972) (Con 2)) (Con 23)); err = (Div (Con 1)(Con 0)); eval :: Term -> M Int; eval (Con a) = (line (Con a) a, a); eval (Div t u) = let (x, a) = eval t in let (y, b) = eval u in (x ++ y ++ line (Div t u) (quot a b), (quot a b)) line :: Term -> Int -> Output; line t a = "eval (" ++ show t ++ ") <= " ++ show a ++ "\n"; main = let (a, b) = eval answer in do putStrLn(a); print(b) -- > eval (Con 1972) <= 1972 -- > eval (Con 2) <= 2 -- > eval (Div (Con 1972) (Con 2)) <= 986 -- > eval (Con 23) <= 23 -- > eval (Div (Div (Con 1972) (Con 2)) (Con 23)) <= 42 -- > 42