Church Encoding is a technique used to represent data and operators in the lambda calculus, named after its inventor, Alonzo Church. Since Haskell is a functional language based on the lambda calculus, we can use Church Encodings to represent data structures and operations only using functions.
Let’s start with the simplest data structure, the boolean. A Church encoded boolean is a higher-order function that takes two arguments and returns one of them based on its value. Here’s the definition of the Church encoded booleans using Haskell:
type ChurchBool = forall a. a -> a -> a
true :: ChurchBool
true x y = x
false :: ChurchBool
false x y = y
With these definitions, we can define boolean operators like "and", "or", and "not":
andC :: ChurchBool -> ChurchBool -> ChurchBool
andC b1 b2 = b1 b2 false
orC :: ChurchBool -> ChurchBool -> ChurchBool
orC b1 b2 = b1 true b2
notC :: ChurchBool -> ChurchBool
notC b = b false true
Now let’s look at Church encoded natural numbers. A Church encoded natural number is a higher-order function that takes a function ‘f‘ and a value ‘x‘. It applies ‘f‘ to the value ‘x‘ that many times as the number represents. Here are the Church encoded versions of zero, one, two, and a general "nat" type:
type ChurchNat = forall a. (a -> a) -> a -> a
zero :: ChurchNat
zero f x = x
one :: ChurchNat
one f x = f x
two :: ChurchNat
two f x = f (f x)
succC :: ChurchNat -> ChurchNat
succC n f x = f (n f x)
In this encoding, we can define arithmetic operations, such as addition, multiplication, and exponentiation:
addC :: ChurchNat -> ChurchNat -> ChurchNat
addC n1 n2 f x = n1 f (n2 f x)
mulC :: ChurchNat -> ChurchNat -> ChurchNat
mulC n1 n2 f x = n1 (n2 f) x
expC :: ChurchNat -> ChurchNat -> ChurchNat
expC n1 n2 = n2 n1
Church Encoding can also be used for more complex data structures, such as the pair or the Maybe type, but be aware that those encodings might not be the most efficient way to represent those types in Haskell. The concept’s main purpose is to demonstrate how different data types can be encoded using only functions in lambda calculus-based languages.