======= 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.
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.