======= 8. The Lambda Calculus ======= 1. Consider the following datatype which encodes λ-expressions: data LExpr = Var Char | Lambda Char LExpr | App LExpr LExpr Enroll ''LExpr'' in class ''Show''. 2. Write a function ''vars'' which returns a list of variables used in a λ-expression: vars :: LExpr -> [Char] 3. Write a function ''reducible'' which tests if an expression can be reduced to another. **Write tests first!** What are the cases when an expression is reducible? reducible :: LExpr -> Bool 4. Write a function which renames **all** occurrences of a variable with another, in a λ-expression: rename :: Char -> Char -> LExpr -> LExpr 5. Write a function which **replaces all** occurrences of a variable with a λ-expression, in a λ-expression: replace :: Char -> LExpr -> LExpr -> LExpr 6. Write a function which takes a λ-expression of the form ''(λx. )'' and **reduces it in a SINGLE step**. - What should ''(λx.(x x) y)'' produce? - What should ''(λx.λx.(x x) y)'' produce? 7. Add two data constructors to the type ''LExpr'' so that we can also model functions and applications in uncurry form. Examples: ''(λx y z.)'', ''(f x y z)''. 8. Write a proper display function for these new constructors. 9. Write a function ''luncurry'' which takes an uncurries λ-expression and transforms it in curry form. lcurry :: LExpr -> LExpr 10. Write a function ''lcurry'' which takes a curried λ-expression and transforms it in uncurry form. (((f x) y) z) becomes (f x y z) (((f ((g a) b)) y) ((h u) v)) becomes (f (g a b) y (h u v)) 11. Write the function ''fv'' which computes the list of all **free variables** of a λ-expression. fv :: LExpr -> [Char] 12. Write a function ''bv'' which computes the list of all **bound variables** of a λ-expression. bv :: LExpr -> [Char] 13. Write a function ''subst'' which computes the //textual substitution of all free occurrences of some variable x by e in e'//, according to the lecture definition: subst :: Char -> LExpr -> LExpr -> LExpr 14. Implement a function which reduces a **reducible** λ-expression to an irreducible one. (According to the lecture definition, what happens with λx.(λx.x x) ? reduce :: LExpr -> LExpr 15. Implement **normal-order** evaluation. 16. Implement **applicative** (strict) evaluation.