Кодирование Чёрча ― способ представления при помощи лямбда-выражений данных, не являющихся функциями и переменными, например, натуральных чисел и других констант. Метод назван в честь Алонзо Чёрча, разработавшего лямбда-исчисление.
Поскольку в чистом (бестиповом) лямбда-исчислении, в отличие от многих формальных систем (где выделены в качестве термов, например, целые числа, булевы значения, пары), единственным примитивным типом являются функции, все остальные виды данных необходимо конструировать с использованием лямбда-выражений. Кодирование подразумевает соглашение о том, как определять те или иные примитивы; например, числа Чёрча — способ кодирования натуральных чисел➤, булеаны Чёрча — соглашение о кодировании логических значений, пары Чёрча➤ — кодирование упорядоченных пар элементов, есть несколько способов закодировать списки➤.
Кодирование Чёрча, как правило, не используется для реализации примитивных типов данных в практических языках программирования из-за неэффективности, но при этом демонстрирует, что любые вычисления могут быть сведены исключительно к функциям и переменным в бестиповом лямбда-исчислении, а другие примитивные типы данных не обязательны.
Число Чёрча, соответствующее натуральному числу , определяется как функция от двух параметров и , применяющая к раз — другими словами, число Чёрча отображает функцию в её -кратную композицию:
.
значит «не применять функцию к вообще», значит «применять функцию 1 раз» и так далее:
Число
Определение нумерала
Лямбда-выражение
⋮
⋮
⋮
Вычисления над числами Чёрча
Арифметические операции над числами можно выразить в лямбда-исчислении как функции над числами Чёрча.
Операция сложения, благодаря тождеству , может быть определена как:
.
Добавление единицы посредством -редукции выводится из сложения:
.
Умножение вводится следующим образом:
.
Операция возведения в степень благодаря определению чисел Чёрча формулируется лаконично:
.
Более сложное выражение требуется для вычитания единицы :
.
Разность двух чисел строится из вычитания единицы:
.
Булеаны Чёрча
Булеаны Чёрча — представления булевых значений, то есть «истины» () и «лжи» () как выбора первого и второго аргумента соответственно:
, .
Некоторые языки программирования, такие как Smalltalk и Pico[англ.], используют их в качестве модели реализации для булевой арифметики.
Предикаты — функции, возвращающие логическое значение — реализуются естественным образом, например, предикат , возвращающий , если его аргумент является числом Чёрча , и в ином случае, вводится таким образом:
,
предикат над числами Чёрча, который проверяет, меньше или равен его первый аргумент второму:
.
Из тождества получается предикат проверки на равенство :
Пары Чёрча — соглашение о кодировании упорядоченных пар, то есть наборов из двух элементов: пара представляется как функция, которая применяет свой единственный аргумент к обоим элементам пары и , получая в результате . Функция образующая пару из аргументов: . Функции и , возвращающие соответственно первый и второй элемент пары:
,
.
Списки
Неизменяемыйсписок из упорядоченных элементов может быть закодирован одним из следующих способов: через создание каждого элемента списка из двух пар, через создание каждого элемента списка из одной пары, через функцию свёртки справа, с использованием кодирования Скотта.
Представление в виде двух пар
При представлении в виде двух пар первый элемент содержит первый элемент списка, а второй — все остальные элементы, «хвост» списка. Поскольку таким способом не может быть выражен пустой список, то используется дополнительная обёртка — первый элемент указывает, является ли список пустым, а второй элемент содержит пару из первого элемента списка и хвоста списка.
Базовые операции со списками в этой схеме кодирования можно выразить следующим образом[1]:
— пустой список;
— возвращает первый элемент пары, который и означает, является ли список пустым;
— конструирует новый непустой список из первого элемента (головы списка) и хвоста ;
— первый элемент пары во втором элементе — голова списка;
— второй элемент пары во втором элементе — хвост списка.
Из этих функций можно вывести остальные необходимые операции для списков, например, определение длины:
.
В пустом списке доступ ко второму элементу никогда не применяется, поскольку к нему не применимы понятия головы и хвоста списка.
Представление в виде одной пары
В качестве альтернативы списки можно определить следующим образом ( здесь соответствует пустому списку, непустые задаются парой головы и хвоста)[2]:
,
,
,
,
.
Представление списка через функцию свёртки справа
В качестве альтернативы кодированию с использованием пар Чёрча список можно закодировать, отождествив его с функцией свёртки справа. Например, список из трёх элементов , и может быть закодирован функцией высшего порядка, которая при применении к комбинатору и значению возвращает :
,
,
,
,
.
Представление списка с использованием кодирования Скотта
↑Jansen, Jan Martin. Programming in the λ-Calculus: From Church to Scott and Back (англ.) // LNCS[англ.] : journal. — 2013. — Vol. 8106. — P. 168—180. — doi:10.1007/978-3-642-40355-2_12.