
Hi, Can someone explain how this lambda is suppose to work, I cannot figure out what it does? data Lambda = Val Double | Add Lambda Lambda | Subtract Lambda Lambda | Multiply Lambda Lambda | Divide Lambda Lambda | Var String | Let String Lambda Lambda deriving Show demo1 = (Add(Multiply(Divide(Subtract(Val 25)(Val 5))(Val 10))(Val 7))(Val 30)) --let x = 1+1 in 3 - x test1 = Let "x" (Add (Val 1) (Val 1)) (Add(Var "x")(Var "x")) test6 = Let "y" (Add (Val 7)(Val 6)) (Subtract (Val 6)(Var "y")) -- 4 * (let x = 1+1 in 3 + x) test2 = Multiply (Val 4) test1 -- x * (let x = 1+1 in 3 + x) test3 = Let "y" (Add (Val 4)(Val 7))(Multiply test1 (Var "y")) test5 = Add (test1) test6 type Dict =[(String,Lambda)]-- dictionary which takes a string and an expression emptyDict :: Dict emptyDict = []-- empty dictionary null set addEntry :: String->Lambda ->Dict -> Dict addEntry= \n e d -> (n,e): d -- add an entry we take a string,expression and a dictionary :gives back dictionary lookupEntry :: String -> Dict -> Maybe Lambda lookupEntry n [] = Nothing lookupEntry n (x:xs) = if (n == k)-- if the entry is equal to then (Just v) else lookupEntry n xs -- find the value of n in the rest of the list where (k,v) = x -- evalStep :: Dict -> Lambda -> Lambda evalStep d (Val x) = (Val x)-- we have a dictionary and a value return the value evalStep d(Add x y)-- dictionary and a add expression of x y = case x of (Val a) -> case y of (Val b) -> Val (a+b) left -> Add x (evalStep d y) right -> Add (evalStep d x)y evalStep d(Subtract x y) = case x of (Val a) -> case y of (Val b) -> Val (a-b) left -> Subtract x (evalStep d y) right -> Subtract (evalStep d x)y evalStep d(Multiply x y) = case x of (Val a) -> case y of (Val b) -> Val (a*b) left -> Multiply x (evalStep d y) right -> Multiply (evalStep d x)y evalStep d (Divide x y) = case x of (Val a) -> case y of (Val b) -> Val (a/b) left -> Divide x (evalStep d y) right -> Divide (evalStep d x)y evalStep d (Let n e1 e2) = case e1 of (Val a) -> case e2 of (Val b)-> Val b left -> evalStep (addEntry n e1 d)e2 right -> evalStep (addEntry n e1 d) e2 evalStep d (Var x) = case lookup x d of Just e -> e Nothing -> error "Error in expression -- no definition for variable!" evaluate :: Dict-> [Lambda] -> Lambda -> IO() evaluate d(x:xs) e = do putStrLn (show e) putStrLn "Do another step (y/n) or rollback (r)? :" c <- getLine case c of "y" -> let e'= (evalStep d e)in evaluate d (e:x:xs) e'-- build up history "r" -> case (x:xs) of (x:xs)-> evaluate d xs x []-> do { putStrLn "Empty" ;evaluate d(x:xs) e } "n" -> putStrLn $ "Ok you said no :" ++ c ev :: Dict-> [Lambda] -> Lambda -> IO() ev = \d (x:xs) e ->do putStrLn (show e) putStrLn "Do another step (y/n) or rollback (r)? :" c <- getLine case c of "y" -> let e'= (evalStep d e)in evaluate d (e:x:xs) e'-- build up history "r" -> case (x:xs) of (x:xs)-> evaluate d xs x []-> do { putStrLn "Empty" ;evaluate d(x:xs) e } "n" -> putStrLn $ "Ok you said no :" ++ c isFree :: String -> Lambda -> Bool isFree n1 (Let n2 e1 e2) |n1 == n2 = False |otherwise = True subst :: String -> Lambda -> Lambda->Lambda subst n e1 e2 |isFree n e2 = subst' n e1 e2 |otherwise = e2 subst' :: String -> Lambda -> Lambda->Lambda subst' n0 e1 (Var n1) |n0 == n1 = e1 |otherwise = Var n1 subst' s v (Add e1 e2) = Add(subst' s v e1)(subst' s v e2) subst' s v (Multiply e1 e2) = Multiply(subst' s v e1)(subst' s v e2) subst' s v (Divide e1 e2) = Divide(subst' s v e1)(subst' s v e2) subst' s v (Subtract e1 e2) = Subtract(subst' s v e1)(subst' s v e2) subst' s v (Let n e1 e2) = Let n (subst' s v e1)(subst' s v e2) John

Hi John I'm not sure it can work properly in its current form. If this is the code that's been posted to the list before, it was originally a calculator with a stepper reduced a calculation a term at at time: input> (+ 3 (- 5 1)) ans> (+ 3 4) "Do another step (y/n) or rollback (r)? :" input> y ans> 7 However once "let" was added, I'm not convinced the evalStep is right as I think it works too greedily and stops evaluating a term at a time, and instead evaluates all sub-terms. Best wishes Stephen
participants (2)
-
John Moore
-
Stephen Tetley