
Am Sonntag 22 November 2009 17:17:46 schrieb John Moore:
Hi All,
I'm trying to work out how to show the steps in evaluating "How the function is calculated". In other words I want this program to actually print out the steps. For e.g. eval (Multiply(Add(Val 10) (Val 20)) (Val 3) Which is add 10+20 and multiply by 3 = 90
The program then produces( Prints out) something like
working: eval (Multiply(Add(Val 10) (Val 20)) (Val 3) working Add(Val10) (Val 20) answer 1 Val 30 answer 2 Val 90
This is what I have so far but it wont even do the calculations. Any help appreciated.
data Expression = Val Float
| Add Expression Expression | Subtract Expression Expression | Multiply Expression Expression | Divide Expression Expression
deriving Show eval :: Expression -> Float eval (Val x) = x eval (Add x y) = eval x + eval y eval (Multiply x y) = eval x * eval y eval (Subtract x y) = eval x - eval y eval (Divide x y) = eval x / eval y
If you want to have the evaluation steps printed, you must do it in IO (after all, your programme will be performing IO) evalIO :: Expression -> IO Float evalIO (Val x) = do putStrLn $ "Plain value " ++ show x return x evalIO (Add x y) = do vx <- evalIO x vy <- evalIO y putStrLn $ "Add " ++ show vx ++ " and " ++ show vy return (vx+vy) ... You can chose other formatting, maybe display the entire expression before evaluating the subexpressions, indent evaluation printout of subexpressions (needs an Int parameter counting how many levels below the top you are for indentation), ... One thing is that by putting it in IO, *you* specify the evaluation order. By itself, faced with eval (Add x y) = eval x + eval y the system may evaluate either subexpression first. You can give the system that freedom back by using Debug.Trace instead of IO, but then there is a nonzero probability that the output of different evaluations becomes entangled (it may evaluate part of x first, then some part of y, more of x,...).
John