From 7541f303846afdbf1f7c5df3d2de9409eae148d3 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Tue, 10 Mar 2026 23:59:33 -0700 Subject: [PATCH] lab10: impl --- lab10/lambdaCalc.lhs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/lab10/lambdaCalc.lhs b/lab10/lambdaCalc.lhs index d11301b..ef8ca3f 100644 --- a/lab10/lambdaCalc.lhs +++ b/lab10/lambdaCalc.lhs @@ -59,9 +59,9 @@ Why does this work? Here are a couple of tests to consider. Define the 'nott' and 'orr' operators below without using andd. -> nott = error "TBD" +> nott = \b -> b fls tru -> orr = error "TBD" +> orr = \b -> \c -> b tru c Here are some test cases: @@ -134,7 +134,7 @@ Write the definition for 'nil' below. (If you are unsure of what the definition should be, try walking through the derivation of "isEmpty (pair 1 2)". -> nil = error "TBD" +> nil = \x -> tru Now we can create some sample lists. (Note that we are using Haskell numbers just for easy of testing, though they are not part of the lambda calculus.) @@ -229,7 +229,9 @@ Alternately, we could define plus with our scc function: Define multiplication in a similar manner: -> multiply = error "TBD" +> multiply = \m -> \n -> m (plus n) zero + +> test3times2 = transChurchNums $ multiply three two For ease of use, you may use the following function to convert a Haskell integer @@ -253,6 +255,11 @@ Haskell will not accept the above combinator. Evaluate this function by hand yourself. After one step, what do you get? +function: (\x -> x x) +argument: (\x -> x x) +substitute x with (\x -> x x) in x x = (\x -> x x) (\x -> x x) +it evaluates to the same function, basically an infinite loop I think? + The omega function is not terribly useful, though it is interesting. We can cause a lambda calculus program to go into an infinite loop. @@ -286,3 +293,25 @@ factorial = fix g To understand how this works, write out the evaluation steps for `factorial 3`. +-> factorial 3 = (fix g) 3 +-> g (fix g) 3 = test (isZero (prd 3)) one (multiply 3 (g (prd 3))) +-> test (isZero (2)) one (multiply 3 (g (2))) +takes the false branch until g (1) then takes the true branch because isZero (prd 1) = true + +> main :: IO () +> main = do +> print $ testTru ++ " : expected true" +> print $ testFls ++ " : expected false" +> print $ testAnd1 ++ " : expected true" +> print $ testAnd2 ++ " : expected false" +> print $ testOps1 ++ " : expected true" +> print $ testOps2 ++ " : expected false" +> print $ testPairFst ++ " : expected true" +> print $ testPairSnd ++ " : expected false" +> print $ show testListHead ++ " : expected 0" +> print $ show testListHeadTail ++ " : expected 1" +> print $ testNotEmpty ++ " : expected false" +> print $ testEmpty ++ " : expected true" +> print $ show test3plus2 ++ " : expected 5" +> print $ show test3times2 ++ " : expected 6" +