Кодирование Чёрча ― способ представления при помощи лямбда-выражений данных, не являющихся функциями и переменными, например, натуральных чисел и других констант. Метод назван в честь Алонзо Чёрча, разработавшего лямбда-исчисление.
Поскольку в чистом (бестиповом) лямбда-исчислении, в отличие от многих формальных систем (где выделены в качестве термов, например, целые числа, булевы значения, пары), единственным примитивным типом являются функции, все остальные виды данных необходимо конструировать с использованием лямбда-выражений. Кодирование подразумевает соглашение о том, как определять те или иные примитивы; например, числа Чёрча — способ кодирования натуральных чисел➤, булеаны Чёрча — соглашение о кодировании логических значений, пары Чёрча➤ — кодирование упорядоченных пар элементов, есть несколько способов закодировать списки➤.
Кодирование Чёрча, как правило, не используется для реализации примитивных типов данных в практических языках программирования из-за неэффективности, но при этом демонстрирует, что любые вычисления могут быть сведены исключительно к функциям и переменным в бестиповом лямбда-исчислении, а другие примитивные типы данных не обязательны.
В статье может быть использована сокращённая λ-нотация для абстракций, .
Число Чёрча, соответствующее натуральному числу , определяется как функция от двух параметров и , последовательно раз применяющая функцию начиная с — другими словами, число Чёрча отображает функцию в её -кратную композицию:
значит «не применять функцию к вообще», значит «применять функцию 1 раз» и так далее:
Соответственно, числo по Скотту это функция, ожидающaя две функции-обработчика, по числу вариантов.
Число по Скотту являет собой уже совершённое сопоставление с образцом, и вызывает соответствующую функцию-обработчик в соответствии с тем, является ли оно нулём или нет. В случае нуля дополнительных данных нет, так что это не функция а просто некая величина , . В случае же не-нулевого числа, дополнительным данным явлается его предшествующее число, например .
В то время как в кодировке Чёрча , в кодировке Скотта , , и . Соответственно и функции перевода в другой тип тоже разнятся,
Как видим, определение перевода чисел Скотта рекурсивно, и требует использования оператора неподвижной точки или соответственного переопределения с использованием само-применения, "вручную":
Предикаты — функции, возвращающие логическое значение — реализуются естественным образом, например, предикат , возвращающий , если его аргумент является числом Чёрча , и в ином случае, вводится таким образом:
,
предикат над числами Чёрча, который проверяет, меньше или равен его первый аргумент второму:
.
Из тождества получается предикат проверки на равенство :
Пары Чёрча — соглашение о кодировании упорядоченных пар, то есть наборов (кортежей) из двух элементов. Пара величин и представляется функцией, которая ожидает как свой единственный аргумент некую функцию , и применяет её к обоим элементам пары, и :
Здесь выступает в роли функции-продолжения, или функции-получателя двух величин из пары.
Функции и , возвращающие соответственно первый и второй элемент пары, а также функция (два варианта, для примера), меняющая местами два элемента пары, определяются как:
Неизменяемыйсписок из упорядоченных элементов может быть закодирован одним из следующих способов: через создание каждого элемента списка из двух пар, через создание каждого элемента списка из одной пары, через функцию свёртки справа, с использованием кодирования Скотта.
При представлении в виде двух пар первый элемент содержит первый элемент списка, а второй — все остальные элементы, «хвост» списка. Поскольку таким способом не может быть выражен пустой список, то используется дополнительная обёртка — первый элемент указывает, является ли список пустым, а второй элемент содержит пару из первого элемента списка и хвоста списка.
Базовые операции со списками в этой схеме кодирования можно выразить следующим образом[2]:
— пустой список;
— возвращает первый элемент пары, который и означает, является ли список пустым;
— конструирует новый непустой список из первого элемента (головы списка) и хвоста ;
— первый элемент пары во втором элементе — голова списка;
— второй элемент пары во втором элементе — хвост списка.
Используя эти функции можно определить остальные необходимые операции для списков, например, определение длины можно записать как:
хотя оно рекурсивно, что недопустимо в лямбда исчислении и требует дальнейшего применения комбинатора неподвижной точки. Возможно и более непосредственное определение, как
В пустом списке доступ ко второму элементу никогда не применяется, поскольку к нему не применимы понятия головы и хвоста списка.
В качестве альтернативы списки можно определить следующим образом ( здесь соответствует пустому списку, непустые задаются парой головы и хвоста)[3]:
Здесь предикат вызывает фунцию-представление списка с функцией продолжения, в качестве первого аргумента, которая получает два аргумента и , голову и хвост списка, в случае если список не пуст; и со значением в качестве второго аргумента, которое будет возвращено, если список пустой. Этот выбор уже произведен, заранее, в момент создания значения .
В качестве альтернативы кодированию с использованием пар, кодировка Чёрча отождествляет список с функцией которая осуществляет его свёртку справа. Например, список из трёх элементов , и представляется функцией , которая ожидает комбинирующую функцию и значение , и возвращает значение свёртки :
Здесь используются мнемонические имена переменных для (голова списка), для (хвост списка), и для рекурсивного результата свертки хвоста списка.
Таким образом, и . Функция определена таким же путём что и функция для чисел Чёрча - передачей комбинирующей функции вперёд по цепочке после её одноразовой замены в самом начале на функцию пропускающую самый первый элемент (и соотвестственно, одноразовой замены функции на функцию тождества в случае чисел Чёрча, для выполнения операции на один раз меньше).
Легко определяются добавочные функции, как например:
Вообще числа по Чёрчу это свертка справа унарного представления натуральных чисел, т.е. списка из неразличимых, неинтересных элементов, длиной равной величине числа. Поэтому соответствует функции , а соответствует , с исключением аргумента в обоих случаях.
Списки - это суммарный тип данных с двумя вариантами. В соответствии с общими принципами кодировки Скотта, каждый список представлен функцией которая ожидает два аргумента, две функции-получателя соответствующие этим двум вариантам: одна для варианта пустого списка и другая для непустого. Функция для непустого варианта получит головной элемент и хвост, а для пустого никаких данных нет, так что это не функция а просто величина:
Таким образом каждая величина в кодировке Скотта представляет собой результат уже произведённого сопоставления с образцами соответствующего типа данных. Например, величина заключает в себе уже произведённый выбор варианта - получив и , она проигнорирует и вызовет с соответствующими данными, и .
Как числа по Чёрчу соответствуют спискам по Чёрчу с игнорированием их элементов, так же и для кодировок Скотта.
↑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.