
Hi I'm trying to get a if statement to work but not sure if this is the right approach, what I want to do in simple english is to evaluate one expression at a time for example. (3+2)+(4+5) I want it to return 5 + (4+5) then 5+9. data Expression = Val Integer | Add Expression Expression | Subtract Expression Expression | Multiply Expression Expression | Divide Expression Expression deriving Show evalStep :: Expression -> Expression evalStep (Val x)= (Val x) evalStep (Add x y) = do if x = isDigit then if y isDigit else evalStep x,y I thinking about using recursion down a tree left then right but that seems very complicated. Any thoughts welcome! John

On Sat, Jan 23, 2010 at 6:40 PM, John Moore
Hi I'm trying to get a if statement to work but not sure if this is the right approach, what I want to do in simple english is to evaluate one expression at a time for example. (3+2)+(4+5) I want it to return 5 + (4+5) then 5+9.
data Expression = Val Integer | Add Expression Expression | Subtract Expression Expression | Multiply Expression Expression | Divide Expression Expression deriving Show evalStep :: Expression -> Expression evalStep (Val x)= (Val x) evalStep (Add x y) = do
if x = isDigit then if y isDigit else evalStep x,y
I thinking about using recursion down a tree left then right but that seems very complicated. Any thoughts welcome! John
I renamed your Expression data type to simply E. Saves some typing :-) data E = Val Integer | Add E E | Sub E E | Mul E E | Div E E deriving Show evalStep :: E -> E evalStep (Val x) = (Val x) -- Note that with a pattern match you can look deeply into a structure. -- in this case we match on the addition of two values. evalStep (Add (Val a) (Val b)) = Val (a + b) evalStep (Add x@(Val _) y) = Add x (evalStep y) evalStep (Add x y@(Val _)) = Add (evalStep x) y You can copy the equations with "Add" and substitute with Sub, Mul and Div and their related functions (-), (*) and div to get the complete evalStep function. Regards, Roel

Hi John, You've several errors. What is isDigit? Let's start reading your code like the compiler does:
evalStep (Add x y) = do Fine Add x y thus both x and y are of type Expression because the constructor Add has been defined this way: | Add Expression Expression
Now let's have a look at this line:
if x = isDigit
if x = isDigit What is isDigit ? Hoogle shows there is a isDigit function you didn't import. http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-Char.htm... It's type is isDigit :: Char -> Bool So your if statement reads as if x is a function ? You can't compare a function with a value "x". Anyway you want == not = to compare for equality. At this point I stop parsing your code because it doesn't make sense at all. You usually use pattern matching for this kind of stuff: evalStep (Add x y) = case x of Val xval -> case y of Val yval -> (evalStep xval) + (evalStep yval) _ -> error "don't know what to do" _ -> error "don't know what to do" This is too verbose. It doesn't make sense to write it this way. Let's do it right ( I feel like doing ones homework here...) but I don't implement every case so I don't feel guilty :) Step by step: evalStep (Add x y) = let xEvaled = evalStep x yEvaled = evalStep y in Val (xEvaled + yEvaled) evalStep( Multiply a b) = error "TODO implement multiply" evalStep _ = error "TODO (everything else I didn't match explicitely)" shorter (that's what I would do:) evalStep (Add x y) = Val $ (evalStep x) + (evalStep y) or even shorter: evalStep (Add x y) = Val $ evalStep `on` (+) x y `on` applies a function to both operands before applying the operand. Summary: Whenever you want to use if .. else or a switch .. case .. thing remember that Haskell does have pattern matching and you should use it. Your isDigit function could be implemented using pattern matching (in fact it's the only way I know about). It looks like this: isDigit (Val _) = true -- Val is a digit isDigit _ = false -- everything else is not Then you could use if isDigit val then .. else .. but it still doesn't make much sense because you still have to get the val out of the constructor. Example: if isDigit val then let Val x = val -- now you can use x (which is Int) to use primitive +/-* operations in x * 2 else .. It doesn't hurt visiting the haskell.org page and reading some tutorials. HTH Marc Weber

Sorry I missed something:
evalStep (Add x y) = let (Val xEvaled) = evalStep x (Val yEvaled) = evalStep y in Val (xEvaled + yEvaled)
should work. So you either have to use this let binding or you have to add a getVal function. And this is why I love Haskell. By thinking about the code you notice that you really want evalStep :: Expression -> result where result is Float, Int or Ratianal or such. Then you can use the code I wrote in my previous mail. Marc Weber

Am Samstag 23 Januar 2010 18:40:10 schrieb John Moore:
Hi I'm trying to get a if statement to work but not sure if this is the right approach,
I think pattern matching and case .. of would be better suited.
what I want to do in simple english is to evaluate one expression at a time for example. (3+2)+(4+5) I want it to return 5 + (4+5) then 5+9.
data Expression = Val Integer
| Add Expression Expression | Subtract Expression Expression | Multiply Expression Expression | Divide Expression Expression
deriving Show evalStep :: Expression -> Expression evalStep (Val x)= (Val x)
evalStep (Add x y) = do
if x = isDigit then if y isDigit else evalStep x,y
-- evaluate one step only evalStep (Add x y) = case x of (Val v) -> case y of (Val w) -> Val (v+w) other -> Add x (evalStep y) other -> Add (evalStep x) y evalStep (Subtract x y) ... -- analogously, also Multiply and Divide evalStep e = e -- only Val left. Voilà, the leftmost innermost compound expression is reduced if the expression isn't fully evaluated. To completely evaluate: eval :: Expression -> Expression eval e@(Val _) = e eval e = eval (evalStep e)
I thinking about using recursion down a tree left then right but that seems very complicated. Any thoughts welcome! John

John Moore schrieb:
data Expression = Val Integer | Add Expression Expression | Subtract Expression Expression | Multiply Expression Expression | Divide Expression Expression deriving Show
After you've copied your code (several times) for the four cases Add, Subtract, Multiply, and Divide, you may want to consider: data Expression = Val Integer | OpExpr Op Expression Expression data Op = Add | Subtract | Multiply | Divide op2op :: Op -> Integer -> Integer -> Integer op2op op = case op of Add -> (+) Subtract -> (-) Multiply -> (*) Divide -> div (or: type Op = Integer -> Integer -> Integer) Cheers Christian
participants (5)
-
Christian Maeder
-
Daniel Fischer
-
John Moore
-
Marc Weber
-
Roel van Dijk