[Haskell-beginners] explanation
Daniel Fischer
daniel.is.fischer at web.de
Wed Dec 1 21:33:42 CET 2010
On Wednesday 01 December 2010 20:34:31, John Moore wrote:
> Hi ,
> Havent used haskell in a while can someone explain just whats
> happening here. I know what it does, I just can't workout how it does
> it. Only need to explain how the red area works and I can work out the
> rest myself
>
> Regards
>
> John
>
>
> module Rollback where
>
>
> data Expression = Val Double
>
> | Add Expression Expression
> | Subtract Expression Expression
> | Multiply Expression Expression
> | Divide Expression Expression
>
> deriving Show
> demo1 = (Add(Multiply(Divide(Subtract(Val 25)(Val 5))(Val 10))(Val
> 7))(Val 30))
evalStep reduces the Expression one step unless it's a Val, which is
irreducible.
> evalStep :: Expression -> Expression
> evalStep (Val x)= (Val x)
Can't reduce a Val, so leave it as is.
> evalStep (Add x y)
For a non-atomic Expression (here Add), look at the first component/left
branch (an Expression is a binary tree with Vals at the leaves and
arithmetic operations at the branch nodes).
> = case x of
> (Val a) -> case y of
If the left branch is irreducible, look at the right
> (Val b) -> Val (a+b)
If that is also irreducible, add the values and return the irreducible
Expression
> left -> Add x (evalStep y)
otherwise reduce the right branch one step (recur).
> right -> Add (evalStep x)y
If the left branch is reducible, reduce it one step (recur), leaving the
right unchanged.
> evalStep (Subtract x y)
> = case x of
> (Val a) -> case y of
> (Val b) -> Val (a-b)
> left -> Subtract x (evalStep y)
> right -> Subtract (evalStep x)y
> evalStep (Multiply x y)
> = case x of
> (Val a) -> case y of
> (Val b) -> Val (a*b)
> left -> Multiply x (evalStep y)
> right -> Multiply (evalStep x)y
>
> evalStep (Divide x y)
> = case x of
> (Val a) -> case y of
> (Val b) -> Val (a/b)
> left -> Divide x (evalStep y)
> right -> Divide (evalStep x)y
> type Stack = [Expression]
> evaluate :: Expression -> IO ()
> evaluate exp = do
> stk <- evalWithStack exp [exp]
> putStrLn "End of Equation"
>
>
> evalWithStack :: Expression -> Stack -> IO Stack
> -- Base case
> evalWithStack (Val a) stk = return stk
> -- Recursive case
> evalWithStack e stk = do
> putStrLn "Evaluating one more step"
> let e' = (evalStep e)
> putStrLn ("Result is "++(show e'))
> putStrLn "Do another step (y/n) or rollback (r)? :"
> c <- getLine
> case c of
> "y" -> evalWithStack e' (e':stk)
> "r" -> let (a,stk') = stackBack stk in evalWithStack a stk'
> "n" -> do { putStrLn ("Ok you said :" ++ show c
> ++ "so that's it "
> ++ "You went as deep as " ++
> show (getCount stk) ++" levels")
> ; return (e': stk)
> }
>
> stackBack :: Stack -> (Expression,Stack)
> stackBack [a] = (a,[a])
> stackBack (a:as) = (a,as)
> stackBack [] = error "Nothing there"
>
> getCount :: Stack -> Int
> getCount stk = length stk
More information about the Beginners
mailing list