HOME

TheInfoList



OR:

In
mathematics Mathematics is a field of study that discovers and organizes methods, Mathematical theory, theories and theorems that are developed and Mathematical proof, proved for the needs of empirical sciences and mathematics itself. There are many ar ...
, Church encoding is a means of representing data and operators in the
lambda calculus In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
. The Church numerals are a representation of the natural numbers using lambda notation. The method is named for
Alonzo Church Alonzo Church (June 14, 1903 – August 11, 1995) was an American computer scientist, mathematician, logician, and philosopher who made major contributions to mathematical logic and the foundations of theoretical computer science. He is bes ...
, who first encoded data in the lambda calculus this way. Terms that are usually considered primitive in other notations (such as integers, Booleans, pairs, lists, and tagged unions) are mapped to
higher-order function In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following: * takes one or more functions as arguments (i.e. a procedural parameter, which is a parameter of a procedure that is itself ...
s under Church encoding. The
Church–Turing thesis In Computability theory (computation), computability theory, the Church–Turing thesis (also known as computability thesis, the Turing–Church thesis, the Church–Turing conjecture, Church's thesis, Church's conjecture, and Turing's thesis) ...
asserts that any computable operator (and its operands) can be represented under Church encoding. In the
untyped lambda calculus In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computation based on function abstraction and application using variable binding and substitution. Untyped lambda calculus, the topic ...
the only primitive data type is the function.


Use

A straightforward implementation of Church encoding slows some access operations from O(1) to O(n), where n is the size of the
data structure In computer science, a data structure is a data organization and storage format that is usually chosen for Efficiency, efficient Data access, access to data. More precisely, a data structure is a collection of data values, the relationships amo ...
, making Church encoding impractical. Research has shown that this can be addressed by targeted optimizations, but most
functional programming In computer science, functional programming is a programming paradigm where programs are constructed by Function application, applying and Function composition (computer science), composing Function (computer science), functions. It is a declarat ...
languages instead expand their intermediate representations to contain
algebraic data type In computer programming, especially functional programming and type theory, an algebraic data type (ADT) is a kind of composite data type, i.e., a data type formed by combining other types. Two common classes of algebraic types are product ty ...
s. Nonetheless Church encoding is often used in theoretical arguments, as it is a natural representation for partial evaluation and theorem proving. Operations can be typed using higher-ranked types, and primitive recursion is easily accessible. The assumption that functions are the only primitive data types streamlines many proofs. Church encoding is complete but only representationally. Additional functions are needed to translate the representation into common data types, for display to people. It is not possible in general to decide if two functions are extensionally equal due to the undecidability of equivalence from Church's theorem. The translation may apply the function in some way to retrieve the value it represents, or look up its value as a literal lambda term. Lambda calculus is usually interpreted as using intensional equality. There are potential problems with the interpretation of results because of the difference between the intensional and extensional definition of equality.


Church numerals

Church numerals are the representations of
natural number In mathematics, the natural numbers are the numbers 0, 1, 2, 3, and so on, possibly excluding 0. Some start counting with 0, defining the natural numbers as the non-negative integers , while others start with 1, defining them as the positive in ...
s under Church encoding. The
higher-order function In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following: * takes one or more functions as arguments (i.e. a procedural parameter, which is a parameter of a procedure that is itself ...
that represents natural number ''n'' is a function that maps any function f to its ''n''-fold composition. In simpler terms, the "value" of the numeral is equivalent to the number of times the function encapsulates its argument. : f^ = \underbrace_.\, All Church numerals are functions that take two parameters. Church numerals 0, 1, 2, ..., are defined as follows in the
lambda calculus In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
. ''Starting with'' 0 ''not applying the function at all, proceed with'' 1 ''applying the function once, 2 ''applying the function twice, 3 ''applying the function three times, etc.'': : \begin \text & \text & \text \\ \hline 0 & 0\ f\ x = x & 0 = \lambda f.\lambda x.x \\ 1 & 1\ f\ x = f\ x & 1 = \lambda f.\lambda x.f\ x \\ 2 & 2\ f\ x = f\ (f\ x) & 2 = \lambda f.\lambda x.f\ (f\ x) \\ 3 & 3\ f\ x = f\ (f\ (f\ x)) & 3 = \lambda f.\lambda x.f\ (f\ (f\ x)) \\ \vdots & \vdots & \vdots \\ n & n\ f\ x = f^n\ x & n = \lambda f.\lambda x.f^\ x \end The Church numeral 3 represents the action of applying any given function three times to a value. The supplied function is first applied to a supplied parameter and then successively to its own result. The end result is not the numeral 3 (unless the supplied parameter happens to be 0 and the function is a
successor function In mathematics, the successor function or successor operation sends a natural number to the next one. The successor function is denoted by ''S'', so ''S''(''n'') = ''n'' +1. For example, ''S''(1) = 2 and ''S''(2) = 3. The successor functio ...
). The function itself, and not its end result, is the Church numeral 3. The Church numeral 3 means simply to do anything three times. It is an ostensive demonstration of what is meant by "three times".


Calculation with Church numerals

Arithmetic Arithmetic is an elementary branch of mathematics that deals with numerical operations like addition, subtraction, multiplication, and division. In a wider sense, it also includes exponentiation, extraction of roots, and taking logarithms. ...
operations on numbers may be represented by functions on Church numerals. These functions may be defined in
lambda calculus In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
, or implemented in most functional programming languages (see converting lambda expressions to functions). The addition function \operatorname(m, n)= m+n uses the identity f^(x)=f^(f^(x)). : \operatorname \equiv \lambda m.\lambda n.\lambda f.\lambda x. m\ f\ (n\ f\ x) The successor function \operatorname(n)=n+1 is β-equivalent to (\operatorname\ 1). : \operatorname \equiv \lambda n.\lambda f.\lambda x. f\ (n\ f\ x) The multiplication function \operatorname(m, n) = m*n uses the identity f^(x) = (f^)^(x). : \operatorname \equiv \lambda m.\lambda n.\lambda f.\lambda x. m\ (n\ f)\ x The exponentiation function \operatorname(b, n) = b^n is given by the definition of Church numerals, n\ h\ x = h^n\ x . In the definition substitute h \to b, x \to f to get n\ b\ f = b^n\ f and, : \operatorname\ b\ n = b^n = n\ b which gives the lambda expression, : \operatorname \equiv \lambda b.\lambda n. n\ b The \operatorname(n) function is more difficult to understand. : \operatorname \equiv \lambda n.\lambda f.\lambda x. n\ (\lambda g.\lambda h. h\ (g\ f))\ (\lambda u. x)\ (\lambda u. u) A Church numeral applies a function ''n'' times. The predecessor function must return a function that applies its parameter ''n - 1'' times. This is achieved by building a container around ''f'' and ''x'', which is initialized in a way that omits the application of the function the first time. See predecessor for a more detailed explanation. The subtraction function can be written based on the predecessor function. : \operatorname \equiv \lambda m.\lambda n. (n \operatorname)\ m


Table of functions on Church numerals

Notes:


Derivation of predecessor function

The predecessor function used in the Church encoding is, :\operatorname(n) = \begin 0 & \mboxn=0, \\ n-1 & \mbox\end. We need a way of applying the function 1 fewer times to build the predecessor. A numeral applies the function times to . The predecessor function must use the numeral to apply the function times. Before implementing the predecessor function, here is a scheme that wraps the value in a container function. We will define new functions to use in place of and , called and . The container function is called . The left-hand side of the table shows a numeral applied to and . : \begin \text & \text & \text \\ \hline 0 & \operatorname = \operatorname\ x & \\ 1 & \operatorname\ \operatorname = \operatorname\ (f\ x) & \operatorname\ \operatorname = \operatorname\ x \\ 2 & \operatorname\ (\operatorname\ \operatorname) = \operatorname\ (f\ (f\ x)) & \operatorname\ (\operatorname\ \operatorname) = \operatorname\ (f\ x) \\ 3 & \operatorname\ (\operatorname\ (\operatorname\ \operatorname)) = \operatorname\ (f\ (f\ (f\ x))) & \operatorname\ (\operatorname\ (\operatorname\ \operatorname)) = \operatorname\ (f\ (f\ x)) \\ \vdots & \vdots & \vdots \\ n & n \operatorname\ \operatorname = \operatorname\ (f^n\ x) = \operatorname\ (n\ f\ x) & n \operatorname\ \operatorname = \operatorname\ (f^\ x) = \operatorname\ ((n-1)\ f\ x) \\ \end The general recurrence rule is, : \operatorname\ (\operatorname\ v) = \operatorname\ (f\ v) If there is also a function to retrieve the value from the container (called ), : \operatorname\ (\operatorname\ v) = v Then may be used to define the function as, : \operatorname = \lambda n.\lambda f.\lambda x.\operatorname\ (n \operatorname \operatorname) = \lambda n.\lambda f.\lambda x.\operatorname\ (\operatorname\ (n\ f\ x)) = \lambda n.\lambda f.\lambda x.n\ f\ x = \lambda n.n The function is not intrinsically useful. However, as delegates calling of to its container argument, we can arrange that on the first application receives a special container that ignores its argument allowing to skip the first application of . Call this new initial container . The right-hand side of the above table shows the expansions of . Then by replacing with in the expression for the function we get the predecessor function, : \operatorname = \lambda n.\lambda f.\lambda x.\operatorname\ (n \operatorname \operatorname) = \lambda n.\lambda f.\lambda x.\operatorname\ (\operatorname\ ((n-1)\ f\ x)) = \lambda n.\lambda f.\lambda x.(n-1)\ f\ x = \lambda n.(n-1) As explained below the functions , , , and may be defined as, :\begin \operatorname &= \lambda v.(\lambda h.h\ v) \\ \operatorname k &= k\ \lambda u.u \\ \operatorname &= \lambda g.\lambda h.h\ (g\ f) \\ \operatorname &= \lambda h.h\ x \\ \operatorname &= \lambda u.x \end Which gives the lambda expression for as, : \operatorname = \lambda n.\lambda f.\lambda x.n\ (\lambda g.\lambda h.h\ (g\ f))\ (\lambda u.x)\ (\lambda u.u)


Another explanation of pred

A much simpler presentation is enabled using combinators notation. : K x y = x : I x = x : X f r i = i (r f) : Pred\ n f x = n (X f) (K x) I Now it is easy enough to see that : Pred\ (Succ\ n) f x = Succ\ n (X f) (K x) I = X f (n (X f) (K x)) I : \ \ \ \ = I (n (X f) (K x) f) =\ ...\ = I (f (f ... (f (K x f)) ...)) = I (n f x) = n f x : Pred\ Zero\ f x =\ Zero (X f) (K x) I =\ K x I =\ x =\ Zero\ f x i.e. by eta-contraction, and then by induction, : Pred\ (Succ\ n) = n : Pred\ Zero = Zero : Pred\ (Pred\ Zero) =\ Pred\ Zero =\ Zero etc.


Another way of defining pred

Pred may also be defined using pairs: :\begin \operatorname =&\ \lambda p.\ \operatorname\ (\operatorname\ p)\ (\operatorname\ (\operatorname\ p)) \\ \operatorname =&\ (\lambda f.\lambda x.\ x) \\ \operatorname =&\ \operatorname\ \operatorname\ \operatorname \\ \operatorname =&\ \lambda n.\ \operatorname\ (n\ \operatorname\ \operatorname) \\ \end This is a simpler definition but leads to a more complex expression for pred. The expansion for \operatorname \operatorname: :\begin \operatorname \operatorname =&\ \operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ \operatorname\ \operatorname)))) \\ =&\ \operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ \operatorname\ \operatorname))) \\ =&\ \operatorname\ (\operatorname\ (\operatorname\ \operatorname\ \operatorname)) \\ =&\ \operatorname\ (\operatorname\ \operatorname\ \operatorname) \\ =&\ \operatorname \end


Division

Division of natural numbers may be implemented by, : n/m = \operatorname\ n \ge m\ \operatorname\ 1 + (n-m)/m\ \operatorname\ 0 Calculating n-m takes many beta reductions. Unless doing the reduction by hand, this doesn't matter that much, but it is preferable to not have to do this calculation twice. The simplest predicate for testing numbers is ''IsZero'' so consider the condition. : \operatorname\ (\operatorname\ n\ m) But this condition is equivalent to n \le m , not n. If this expression is used then the mathematical definition of division given above is translated into function on Church numerals as, : \operatorname\ n\ m\ f\ x = (\lambda d.\operatorname\ d\ (0\ f\ x)\ (f\ (\operatorname\ d\ m\ f\ x)))\ (\operatorname\ n\ m) As desired, this definition has a single call to \operatorname\ n\ m . However the result is that this formula gives the value of (n-1)/ m. This problem may be corrected by adding 1 to ''n'' before calling ''divide''. The definition of ''divide'' is then, : \operatorname\ n = \operatorname\ (\operatorname\ n) ''divide1'' is a recursive definition. The
Y combinator Y Combinator, LLC (YC) is an American technology startup accelerator and venture capital firm launched in March 2005 which has been used to launch more than 5,000 companies. The accelerator program started in Boston and Mountain View, Californi ...
may be used to implement the recursion. Create a new function called ''div'' by; * In the left hand side \operatorname \rightarrow \operatorname \ c * In the right hand side \operatorname \rightarrow c to get, : \operatorname = \lambda c.\lambda n.\lambda m.\lambda f.\lambda x.(\lambda d.\operatorname\ d\ (0\ f\ x)\ (f\ (c\ d\ m\ f\ x)))\ (\operatorname\ n\ m) Then, : \operatorname = \lambda n.\operatorname\ (\operatorname\ n) where, : \begin \operatorname &= Y\ \operatorname \\ \operatorname &= \lambda n.\lambda f.\lambda x. f\ (n\ f\ x) \\ Y &= \lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x)) \\ 0 &= \lambda f.\lambda x.x\\ \operatorname &= \lambda n.n\ (\lambda x.\operatorname)\ \operatorname \end :: \begin \operatorname &\equiv \lambda a.\lambda b.a\\ \operatorname &\equiv \lambda a.\lambda b.b \end : \begin \operatorname &= \lambda m.\lambda n.n \operatorname m\\ \operatorname &= \lambda n.\lambda f.\lambda x.n\ (\lambda g.\lambda h.h\ (g\ f))\ (\lambda u.x)\ (\lambda u.u) \end Gives, : \scriptstyle \operatorname = \lambda n.((\lambda f.(\lambda x.x\ x)\ (\lambda x.f\ (x\ x)))\ (\lambda c.\lambda n.\lambda m.\lambda f.\lambda x.(\lambda d.(\lambda n.n\ (\lambda x.(\lambda a.\lambda b.b))\ (\lambda a.\lambda b.a))\ d\ ((\lambda f.\lambda x.x)\ f\ x)\ (f\ (c\ d\ m\ f\ x)))\ ((\lambda m.\lambda n.n (\lambda n.\lambda f.\lambda x.n\ (\lambda g.\lambda h.h\ (g\ f))\ (\lambda u.x)\ (\lambda u.u)) m)\ n\ m)))\ ((\lambda n.\lambda f.\lambda x. f\ (n\ f\ x))\ n) Or as text, using \ for , divide = (\n.((\f.(\x.x x) (\x.f (x x))) (\c.\n.\m.\f.\x.(\d.(\n.n (\x.(\a.\b.b)) (\a.\b.a)) d ((\f.\x.x) f x) (f (c d m f x))) ((\m.\n.n (\n.\f.\x.n (\g.\h.h (g f)) (\u.x) (\u.u)) m) n m))) ((\n.\f.\x. f (n f x)) n)) For example, 9/3 is represented by divide (\f.\x.f (f (f (f (f (f (f (f (f x))))))))) (\f.\x.f (f (f x))) Using a lambda calculus calculator, the above expression reduces to 3, using normal order. \f.\x.f (f (f (x)))


Signed numbers

One simple approach for extending Church Numerals to signed numbers is to use a Church pair, containing Church numerals representing a positive and a negative value. The integer value is the difference between the two Church numerals. A natural number is converted to a signed number by, :\operatorname_s = \lambda x.\operatorname\ x\ 0 Negation is performed by swapping the values. :\operatorname_s = \lambda x.\operatorname\ (\operatorname\ x)\ (\operatorname\ x) The integer value is more naturally represented if one of the pair is zero. The ''OneZero'' function achieves this condition, :\operatorname = \lambda x.\operatorname\ (\operatorname\ x)\ x\ (\operatorname\ (\operatorname\ x)\ x\ (\operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ x))\ (\operatorname\ (\operatorname\ x))))) The recursion may be implemented using the Y combinator, :\operatorname = \lambda c.\lambda x.\operatorname\ (\operatorname\ x)\ x\ (\operatorname\ (\operatorname\ x)\ x\ (c\ (\operatorname\ (\operatorname\ (\operatorname\ x))\ (\operatorname\ (\operatorname\ x))))) :\operatorname = Y \operatorname


Plus and minus

Addition is defined mathematically on the pair by, :x + y = _p, x_n+ _p, y_n= x_p - x_n + y_p - y_n = (x_p + y_p) - (x_n + y_n) = _p + y_p, x_n + y_n The last expression is translated into lambda calculus as, :\operatorname_s = \lambda x.\lambda y.\operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y))\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y))) Similarly subtraction is defined, :x - y = _p, x_n- _p, y_n= x_p - x_n - y_p + y_n = (x_p + y_n) - (x_n + y_p) = _p + y_n, x_n + y_p giving, :\operatorname_s = \lambda x.\lambda y.\operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y))\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y)))


Multiply and divide

Multiplication may be defined by, :x*y = _p, x_n _p, y_n=(x_p - x_n)*(y_p - y_n) = (x_p*y_p + x_n*y_n) - (x_p*y_n + x_n*y_p) = _p*y_p + x_n*y_n, x_p*y_n + x_n*y_p/math> The last expression is translated into lambda calculus as, :\operatorname_s = \lambda x.\lambda y.\operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y))\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y)))\ (\operatorname\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y))\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y))) A similar definition is given here for division, except in this definition, one value in each pair must be zero (see ''OneZero'' above). The ''divZ'' function allows us to ignore the value that has a zero component. :\operatorname = \lambda x.\lambda y.\operatorname\ y\ 0 \ (\operatorname\ x\ y) ''divZ'' is then used in the following formula, which is the same as for multiplication, but with ''mult'' replaced by ''divZ''. :\operatorname_s = \lambda x.\lambda y.\operatorname\ (\operatorname\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y))\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y)))\ (\operatorname\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y))\ (\operatorname\ (\operatorname\ x)\ (\operatorname\ y)))


Rational and real numbers

Rational and computable real numbers may also be encoded in lambda calculus. Rational numbers may be encoded as a pair of signed numbers. Computable real numbers may be encoded by a limiting process that guarantees that the difference from the real value differs by a number which may be made as small as we need. The references given describe software that could, in theory, be translated into lambda calculus. Once real numbers are defined, complex numbers are naturally encoded as a pair of real numbers. The data types and functions described above demonstrate that any data type or calculation may be encoded in lambda calculus. This is the
Church–Turing thesis In Computability theory (computation), computability theory, the Church–Turing thesis (also known as computability thesis, the Turing–Church thesis, the Church–Turing conjecture, Church's thesis, Church's conjecture, and Turing's thesis) ...
.


Translation with other representations

Most real-world languages have support for machine-native integers; the ''church'' and ''unchurch'' functions convert between nonnegative integers and their corresponding Church numerals. The functions are given here in
Haskell Haskell () is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research, and industrial applications, Haskell pioneered several programming language ...
, where the \ corresponds to the λ of Lambda calculus. Implementations in other languages are similar. type Church a = (a -> a) -> a -> a church :: Integer -> Church Integer church 0 = \f -> \x -> x church n = \f -> \x -> f (church (n-1) f x) unchurch :: Church Integer -> Integer unchurch cn = cn (+ 1) 0


Church Booleans

''Church Booleans'' are the Church encoding of the Boolean values ''true'' and ''false.'' Some programming languages use these as an implementation model for Boolean arithmetic; examples are
Smalltalk Smalltalk is a purely object oriented programming language (OOP) that was originally created in the 1970s for educational use, specifically for constructionist learning, but later found use in business. It was created at Xerox PARC by Learni ...
and Pico. Boolean logic may be considered as a choice. The Church encoding of ''true'' and ''false'' are functions of two parameters: * ''true'' chooses the first parameter. * ''false'' chooses the second parameter. The two definitions are known as Church Booleans: : \begin \operatorname &\equiv \lambda a.\lambda b.a\\ \operatorname &\equiv \lambda a.\lambda b.b \end This definition allows predicates (i.e. functions returning logical values) to directly act as if-clauses. A function returning a Boolean, which is then applied to two parameters, returns either the first or the second parameter: : \operatornamex\ \operatorname\ \operatorname evaluates to ''then-clause'' if ''predicate-x'' evaluates to ''true'', and to ''else-clause'' if ''predicate-x'' evaluates to ''false''. Because ''true'' and ''false'' choose the first or second parameter they may be combined to provide logic operators. Note that there are multiple possible implementations of ''not''. : \begin \operatorname &= \lambda p.\lambda q.p\ q\ p\\ \operatorname &= \lambda p.\lambda q.p\ p\ q\\ \operatorname_1 &= \lambda p.\lambda a.\lambda b.p\ b\ a\\ \operatorname_2 &= \lambda p.p\ (\lambda a.\lambda b. b)\ (\lambda a.\lambda b. a) = \lambda p.p \operatorname \operatorname\\ \operatorname &= \lambda a.\lambda b.a\ (\operatorname\ b)\ b\\ \operatorname &= \lambda p.\lambda a.\lambda b.p\ a\ b \end Some examples: : \begin \operatorname \operatorname \operatorname &= (\lambda p.\lambda q.p\ q\ p)\ \operatorname\ \operatorname = \operatorname \operatorname \operatorname = (\lambda a.\lambda b.a) \operatorname \operatorname = \operatorname \\ \operatorname \operatorname \operatorname &= (\lambda p.\lambda q.p\ p\ q)\ (\lambda a.\lambda b.a)\ (\lambda a.\lambda b.b) = (\lambda a.\lambda b.a)\ (\lambda a.\lambda b.a)\ (\lambda a.\lambda b.b) = (\lambda a.\lambda b.a) = \operatorname \\ \operatorname_1\ \operatorname &= (\lambda p.\lambda a.\lambda b.p\ b\ a) (\lambda a.\lambda b.a) = \lambda a.\lambda b.(\lambda a.\lambda b.a)\ b\ a = \lambda a.\lambda b.(\lambda c.b)\ a = \lambda a.\lambda b.b = \operatorname \\ \operatorname_2\ \operatorname &= (\lambda p.p\ (\lambda a.\lambda b. b) (\lambda a.\lambda b. a)) (\lambda a.\lambda b. a) = (\lambda a.\lambda b. a) (\lambda a.\lambda b. b) (\lambda a.\lambda b. a) = (\lambda b. (\lambda a.\lambda b. b))\ (\lambda a.\lambda b. a) = \lambda a.\lambda b.b = \operatorname \end


Predicates

A ''predicate'' is a function that returns a Boolean value. The most fundamental predicate is \operatorname, which returns \operatorname if its argument is the Church numeral 0, and \operatorname if its argument is any other Church numeral: : \operatorname = \lambda n.n\ (\lambda x.\operatorname)\ \operatorname The following predicate tests whether the first argument is less-than-or-equal-to the second: : \operatorname = \lambda m.\lambda n.\operatorname\ (\operatorname\ m\ n), Because of the identity, : x = y \equiv (x \le y \land y \le x) The test for equality may be implemented as, : \operatorname = \lambda m.\lambda n.\operatorname\ (\operatorname\ m\ n)\ (\operatorname\ n\ m)


Church pairs

Church pairs are the Church encoding of the pair (two-tuple) type. The pair is represented as a function that takes a function argument. When given its argument it will apply the argument to the two components of the pair. The definition in
lambda calculus In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
is, : \begin \operatorname &\equiv \lambda x.\lambda y.\lambda z.z\ x\ y \\ \operatorname &\equiv \lambda p.p\ (\lambda x.\lambda y.x) \\ \operatorname &\equiv \lambda p.p\ (\lambda x.\lambda y.y) \end For example, : \begin & \operatorname\ (\operatorname\ a\ b) \\ = & (\lambda p.p\ (\lambda x.\lambda y.x))\ ((\lambda x.\lambda y.\lambda z.z\ x\ y)\ a\ b) \\ = & (\lambda p.p\ (\lambda x.\lambda y.x))\ (\lambda z.z\ a\ b) \\ = & (\lambda z.z\ a\ b)\ (\lambda x.\lambda y.x) \\ = & (\lambda x.\lambda y.x)\ a\ b = a \end


List encodings

An ( immutable)
list A list is a Set (mathematics), set of discrete items of information collected and set forth in some format for utility, entertainment, or other purposes. A list may be memorialized in any number of ways, including existing only in the mind of t ...
is constructed from list nodes. The basic operations on the list are; We give four different representations of lists below: * Build each list node from two pairs (to allow for empty lists). * Build each list node from one pair. * Represent the list using the right fold function. * Represent the list using Scott's encoding that takes cases of match expression as arguments


Two pairs as a list node

A nonempty list can be implemented by a Church pair; * ''First'' contains the head. * ''Second'' contains the tail. However this does not give a representation of the empty list, because there is no "null" pointer. To represent null, the pair may be wrapped in another pair, giving three values: * ''First'' - the null pointer (empty list). * ''Second.First'' contains the head. * ''Second.Second'' contains the tail. Using this idea the basic list operations can be defined like this: In a ''nil'' node ''second'' is never accessed, provided that head and tail are only applied to nonempty lists.


One pair as a list node

Alternatively, define : \begin \operatorname &\equiv \operatorname \\ \operatorname &\equiv \operatorname \\ \operatorname &\equiv \operatorname \\ \operatorname &\equiv \operatorname \\ \operatorname &\equiv \lambda l.l (\lambda h.\lambda t.\lambda d.\operatorname) \operatorname \\ \end where the last definition is a special case of the general : \begin \operatorname &\equiv \lambda l.l (\lambda h.\lambda t.\lambda d. \operatorname) \operatorname \\ \end Other operations for one pair as a list node : \begin \operatorname &\equiv \lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ t)\ \operatorname \\ \operatorname &\equiv \lambda f.\ \operatorname\ (\lambda r.\lambda a.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ r\ (f\ a\ h)\ t)\ a) \\ \operatorname &\equiv \lambda f.\lambda a.\ \operatorname\ (\lambda r.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ f\ (r\ t)\ h)\ a) \\ \operatorname &\equiv \operatorname\ (\lambda a.\lambda h.\ \operatorname\ a)\ \operatorname \end ---- : \begin \operatorname &\equiv \lambda f. \lambda l.\ \operatorname\ (\lambda a.\lambda h.\ \operatorname\ (f\ h)\ a)\ \operatorname\ l \\ & \equiv \lambda f.\ \operatorname\ (\lambda a.\lambda h.\ \operatorname\ (f\ h)\ a)\ \operatorname \\ \operatorname &\equiv \lambda f. \lambda l.\ \operatorname\ (\lambda a.\lambda h.\ f\ h\ (\operatorname\ h\ a)\ a)\ \operatorname\ l \\ & \equiv \lambda f.\ \operatorname\ (\lambda a.\lambda h.\ f\ h\ (\operatorname\ h\ a)\ a)\ \operatorname \\ \operatorname &\equiv \lambda l.\ \operatorname\ (\lambda a.\lambda h.\ \operatorname\ h\ a)\ \operatorname\ l \\ & \equiv \operatorname\ (\lambda a.\lambda h.\ \operatorname\ h\ a)\ \operatorname \\ \operatorname &\equiv \lambda l. \lambda g.\ \operatorname\ (\lambda a.\lambda h.\ \operatorname\ h\ a)\ g\ l \\ \operatorname &\equiv \lambda l. \lambda v.\ \operatorname\ l\ (\operatorname\ v\ \operatorname) \end ---- : \begin \operatorname &\equiv \lambda n. \lambda l.\ n\ \operatorname\ l \\ & \equiv \lambda n.\ n\ \operatorname \\ & \equiv \operatorname\ (\lambda r.\lambda n.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ \operatorname\ n\ l\ (r\ (\operatorname\ n)\ t))\ \operatorname) \\ \operatorname &\equiv \lambda n. \lambda l.\ \operatorname\ n\ l\ \operatorname ( \\ & \ \ \ \ \operatorname\ (\lambda r.\lambda lr.\ lr\ (\lambda h.\lambda t.\lambda d. \\ & \ \ \ \ \ \ \ \ r\ t\ (\lambda na.\lambda la.\ \operatorname\ na \\ & \ \ \ \ \ \ \ \ \ \ \ \ (\operatorname\ \operatorname\ (\operatorname\ h\ la)) \\ & \ \ \ \ \ \ \ \ \ \ \ \ (\operatorname\ (\operatorname\ na)\ \operatorname) \\ & \ \ \ \ \ \ \ \ )) \\ & \ \ \ \ \ \ \ \ (\operatorname\ n\ \operatorname) \\ & \ \ \ \ )\ l ) \\ \operatorname &\equiv \lambda f.\ \operatorname\ (\lambda r.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ f\ h\ (r\ t)\ l)\ \operatorname) \\ \operatorname &\equiv \operatorname\ (\lambda r.\lambda n.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ \operatorname\ n\ \operatorname\ (\operatorname\ h\ (r\ (\operatorname\ n)\ t)))\ \operatorname) \\ \operatorname &\equiv \lambda n. \lambda l.\ \operatorname\ n\ l\ \operatorname ( \\ & \ \ \ \ \operatorname\ (\lambda r.\lambda lr.\ lr\ (\lambda h.\lambda t.\lambda d. \\ & \ \ \ \ \ \ \ \ r\ t\ (\lambda na.\lambda la.\ \operatorname\ na \\ & \ \ \ \ \ \ \ \ \ \ \ \ (\operatorname\ \operatorname\ la) \\ & \ \ \ \ \ \ \ \ \ \ \ \ (\operatorname\ (\operatorname\ na)\ lr) \\ & \ \ \ \ \ \ \ \ )) \\ & \ \ \ \ \ \ \ \ (\operatorname\ n\ \operatorname) \\ & \ \ \ \ )\ l ) \\ \operatorname &\equiv \lambda f.\ \operatorname\ (\lambda r.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ f\ d\ (\operatorname\ h\ (r\ t))\ \operatorname)\ \operatorname) \end ---- : \begin \operatorname &\equiv \operatorname\ (\lambda r.\lambda f.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ f\ h\ (r\ f\ t)\ \operatorname)\ \operatorname) \\ \operatorname &\equiv \operatorname\ (\lambda r.\lambda f.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ f\ h\ \operatorname\ (r\ f\ t))\ \operatorname) \\ \operatorname &\equiv \lambda n.\lambda l.\ \operatorname\ (\operatorname\ n\ l) \\ \operatorname &\equiv \lambda n.\lambda v.\lambda l.\ \operatorname\ (\operatorname\ n\ l)\ (\operatorname\ v\ (\operatorname\ n\ l)) \\ \operatorname &\equiv \lambda n.\lambda l.\ \operatorname\ (\operatorname\ n\ l)\ (\operatorname\ (\operatorname\ n)\ l) \\ \operatorname &\equiv \lambda n.\lambda v.\lambda l.\ \operatorname\ (\operatorname\ n\ l)\ (\operatorname\ v\ (\operatorname\ (\operatorname\ n)\ l)) \\ \operatorname &\equiv \lambda f.\ \operatorname\ (\lambda r.\lambda n.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ f\ h\ n\ (r\ (\operatorname\ n)\ t))\ \operatorname)\ \operatorname \\ \operatorname &\equiv \lambda f.\ \operatorname\ (\lambda r.\lambda n.\lambda l.\ l\ (\lambda h.\lambda t.\lambda d.\ (\lambda i.\ \operatorname\ i\ (f\ h\ n\ \operatorname)\ i)\ (r\ (\operatorname\ n)\ t))\ \operatorname)\ \operatorname \\ \operatorname &\equiv \lambda f.\lambda z.\ \operatorname\ (\lambda r.\lambda s.\lambda n.\ \operatorname\ n\ \operatorname\ (\operatorname\ (s\ f\ z)\ (r\ (\operatorname\ s)\ (\operatorname\ n))))\ \operatorname \\ \operatorname &\equiv \lambda v.\ \operatorname\ (\lambda r.\lambda n.\ \operatorname\ n\ \operatorname\ (\operatorname\ v\ (r\ (\operatorname\ n)))) \\ \operatorname &\equiv Y\ (\lambda r.\lambda l1.\lambda l2.\ l1\ (\lambda h1.\lambda t1.\lambda d1.\ l2\ (\lambda h2.\lambda t2.\lambda d2.\ \operatorname\ (\operatorname\ h1\ h2)\ (r\ t1\ t2))\ \operatorname)\ \operatorname) \\ \end


Represent the list using ''right fold''

As an alternative to the encoding using Church pairs, a list can be encoded by identifying it with its right fold function. For example, a list of three elements x, y and z can be encoded by a higher-order function that when applied to a combinator c and a value n returns c x (c y (c z n)). Equivalently, it is an application of the chain of functional compositions of partial applications, (c x \circ c y \circ c z) n. : \begin \operatorname &\equiv \lambda c.\lambda n.n\\ \operatorname &\equiv \lambda h.\lambda c.\lambda n.c\ h\ n\\ \operatorname &\equiv \lambda h.\lambda t.\lambda c.\lambda n.c\ h\ (t\ c\ n)\\ \operatorname &\equiv \lambda l.\lambda t.\lambda c.\lambda n.l\ c\ (t\ c\ n)\\ \operatorname &\equiv \lambda l.l\ (\lambda h.\lambda r.\operatorname)\ \operatorname\\ \operatorname &\equiv \lambda l.l\ (\lambda h.\lambda r.true)\ \operatorname\\ \operatorname &\equiv \lambda l.l\ (\lambda h.\lambda r.h)\ \operatorname\\ \operatorname &\equiv \lambda f.\lambda l.\lambda c.\lambda n.l\ (\lambda h.\lambda r.c\ (f\ h)\ r)\ n\\ \operatorname &\equiv \lambda l.\lambda c.\lambda n.l\ (\lambda h.\lambda r.\lambda g.g\ h\ (r\ c))\ (\lambda c.n)\ (\lambda h.\lambda t.t) \end This list representation can be given type in
System F System F (also polymorphic lambda calculus or second-order lambda calculus) is a typed lambda calculus that introduces, to simply typed lambda calculus, a mechanism of universal quantification over types. System F formalizes parametric polymorph ...
. The evident correspondence to Church numerals is non-coincidental, as that can be seen as a unary encoding, with natural numbers represented by lists of unit (i.e. non-important) values, e.g. ) () () with the list's length serving as the representation of the natural number. Right folding over such lists uses functions which necessarily ignore the element's value, and is equivalent to the chained functional composition, i.e. (c () \circ c () \circ c ()) n = (f \circ f \circ f) n, as is used in Church numerals.


Represent the list using Scott encoding

An alternative representation is Scott encoding, which uses the idea of
continuation In computer science, a continuation is an abstract representation of the control state of a computer program. A continuation implements ( reifies) the program control state, i.e. the continuation is a data structure that represents the computat ...
s and can lead to simpler code. (see also Mogensen–Scott encoding). In this approach, we use the fact that lists can be observed using
pattern matching In computer science, pattern matching is the act of checking a given sequence of tokens for the presence of the constituents of some pattern. In contrast to pattern recognition, the match usually must be exact: "either it will or will not be a ...
expression. For example, using Scala notation, if list denotes a value of type List with empty list Nil and constructor Cons(h, t) we can inspect the list and compute nilCode in case the list is empty and when the list is not empty: list match The is given by how it acts upon and . We therefore define a list as a function that accepts such and as arguments, so that instead of the above pattern match we may simply write: : \operatorname\ \operatorname\ \operatorname Let us denote by the parameter corresponding to and by the parameter corresponding to . The empty list is the one that returns the nil argument: : \operatorname \equiv \lambda n. \lambda c.\ n The non-empty list with head and tail is given by : \operatorname\ h\ t\ \ \equiv\ \ \lambda n.\lambda c.\ c\ h\ t More generally, an
algebraic data type In computer programming, especially functional programming and type theory, an algebraic data type (ADT) is a kind of composite data type, i.e., a data type formed by combining other types. Two common classes of algebraic types are product ty ...
with m alternatives becomes a function with m parameters. When the ith constructor has n_i arguments, the corresponding parameter of the encoding takes n_i arguments as well. Scott encoding can be done in untyped lambda calculus, whereas its use with types requires a type system with recursion and type polymorphism. A list with element type E in this representation that is used to compute values of type C would have the following recursive type definition, where '=>' denotes function type: type List = C => // nil argument (E => List => C) => // cons argument C // result of pattern matching A list that can be used to compute arbitrary types would have a type that quantifies over C. A list generic in E would also take E as the type argument.


See also

*
Lambda calculus In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
*
System F System F (also polymorphic lambda calculus or second-order lambda calculus) is a typed lambda calculus that introduces, to simply typed lambda calculus, a mechanism of universal quantification over types. System F formalizes parametric polymorph ...
for Church numerals in a typed calculus * Mogensen–Scott encoding * Von Neumann definition of ordinals — another way to encode natural numbers: as sets


References

* * * All about Church and other similar encodings, including how to derive them and operations on them, from first principles
Some interactive examples of Church numerals
{{Alonzo Church Lambda calculus