This is an old revision of the document!


Lab 7. Lambda Calculus. Intro to Haskell

Short RECAP:
Lambda Calculus represent a axiomatic system that can be used for very basic proofs.
Given a set of variables VARS, a expression under lambda calculus can be:

variable $ x $ $ x \in VARS $
function $ \lambda x.e $ $ x \in VARS $, $ e $ is a $ \lambda $-expression
application $ (e_1 \ e_2) $ $ e_1, e_2 $ are $ \lambda $-expressions

To evaluate $\lambda$-expressions, there are two types of reduction operations:

  • $\alpha$-conversion: given a expression: $ \lambda x.e $, you can rename all occurences of x in e with y (used for avoiding name collisions).
  • $\beta$-reduction: given a expression: $ \lambda x.body \ param$, you can replace all occurences of x in body with param.

Booleans

We can encode boolean values TRUE and FALSE in lambda calculus as functions that take 2 values, x and y, and return the first (for TRUE) or second (for FALSE) value.

$ TRUE = \lambda x.\lambda y.y$
$ FALSE = \lambda x.\lambda y.x$

As we defined it, TRUE is sometimes called the K-Combinator (or Kestrel), and FALSE the KI-Combinator (or Kite).

Click to display ⇲

Click to hide ⇱

Some common operation on booleans (that were discussed during the lecture) are:

$ AND = \lambda x.\lambda y.((x \ y) \ x) $
$ OR = \lambda x.\lambda y.((x \ x) \ y) $
$ NOT = \lambda x.((x \ FALSE) \ TRUE) $

NOT can also be written as:

$ NOT = \lambda x.\lambda a.\lambda b.((x \ b) \ a) $

You can convince yourself that this works by evaluating NOT TRUE and NOT FALSE. This way of writting NOT is also called the C-Combinator (or Cardinal).

Natural Numbers

Church numerals represent natural numbers as higher-order functions. Under this representation, the number n is a function that maps f to its n-fold composition.

$ N0 = \lambda f.\lambda x. x $
$ N1 = \lambda f.\lambda x. (f \ x) $
$ N2 = \lambda f.\lambda x. (f \ (f \ x)) $

Does N0 look familiar? It's the same as FALSE if you rename the variables (using $\alpha$-reduction).

You can also define operation on church numerals, some (that were discussed during the lecture) are:

$ SUCC = \lambda n.\lambda f.\lambda x.(f \ ((n \ f) \ x)) $
$ ISZERO = \lambda n.((n \lambda x.FALSE) \ TRUE) $
$ ADD = \lambda n.\lambda m.\lambda f.\lambda x.((n \ f) ((m \ f) \ x)) $

7.1.1 Define multiplication under church numerals: $ MULT = \lambda n.\lambda m. \ \ldots $ (without using the Y-combinator)

7.1.2 Define exponentiation under church numerals: $ EXP = \lambda n.\lambda m. \ \ldots $

7.1.3 (*) Define the predecessor operator, that takes a number and returns the number prior to it.

What's the predecessor of 0? Evaluate $ PRED \ N0 $.

Click to display ⇲

Click to hide ⇱

$ PRED = \lambda n.\lambda f.\lambda x.(((n \ (\lambda g.\lambda h.h \ (g \ f))) \ (\lambda u.x)) \ (\lambda v.v)) $

$ \phi = \lambda p.PAIR \ (SND \ p) \ (SUCC \ (SND \ p)) $
$ PRED = \lambda.n.FST \ (n \ \phi \ (PAIR \ N0 \ N0)) $


7.1.4 Define substraction under church numerals: $ SUB = \lambda n.\lambda m. \ \ldots $ (Hint: use $ PRED $).

What happens if you try to substract a bigger number from a smaller one? Evaluate $ SUB \ N1 \ N2 $.

7.1.5 Define $ LEQ $ (less or equal). $ LEQ n m $ should return TRUE if $ n \leq m $ and FALSE if $ n > m $.

7.1.6 Define $ EQ $ (equality). $ EQ n m $ should return TRUE if $ n = m $ and FALSE otherwise.

In lambda calculus, recursion is achieved using the fixed-point combinator (or Y combinator).
A fixed-point combinator is a higher-order function that returns some fixed point of it's argument function (x is a fixed pointed for a function f if $ f(x) = x $). That means: $ f \ (fix \ f) = fix \ f $
And by repeated application: $ fix \ f = f \ (f \ (\ldots f \ (fix \ f)\ldots)) $
Our combinator in lambda calculus looks like this:

$ FIX = \lambda f.(\lambda x.f \ (x \ x)) (\lambda x.f \ (x \ x)) $

7.2.1 Using the Y-Combinator, define a function that computes the factorial of a number n.

7.2.2 Using the Y-Combinator, define a function $ FIB $ that computes the n-th fibonacci number.