Ответы:
Сначала закодируйте натуральные числа и пары, как описано в jmad.
Представьте целое число в виде пары натуральных чисел ( a , b ), таких что k = a - b . Затем вы можете определить обычные операции над целыми числами как (используя запись Хаскелла для λ- калькуляции):
neg = \k -> (snd k, fst k)
add = \k m -> (fst k + fst m, snd k + snd m)
sub = \k m -> add k (neg m)
mul = \k m -> (fst k * fst m + snd k * snd m, fst k * snd m + snd k * fst m)
Случай комплексных чисел аналогичен в том смысле, что комплексное число кодируется как пара вещественных чисел. Но более сложный вопрос заключается в том, как кодировать реалы. Здесь вы должны сделать больше работы:
Кодирование реалов - это большая работа, и вы не хотите делать это в калькуляторе. Но посмотрите, например, подкаталог Marshall для простой реализации реалов в чистом Haskell. В принципе это можно перевести на чистый λ- расчет.etc/haskell
i:ℤ, x:a, f,u,s:a→a, p:(a→a,a→a)] Если вы закодировать ℤ , как (Sign,ℕ)то, учитывая пар функций , (s,f)как pэтот термин λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)будет производить либо f(…f(x)…)или s(f(…f(x)…))(если результат отрицательный). Если вы закодируете ℤ как (ℕ,ℕ), вам нужна функция, которая имеет обратное значение - заданная пара (f,u)и x, функция λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)выдаст, u(…u(f(…f(x)…))…)что оставит fприложенное iвремя до x. Оба работают в разных контекстах (результат может быть «перевернут» || fявляется обратимым).
fold . ctorдля любого конструктора и этого типа fold( r). (Именно поэтому, для рекурсивных типов, данные будут «рекурсия на своем» Для не рекурсивных типов это больше похожи. case/ Матч шаблона.)
Лямбда-исчисление может кодировать большинство структур данных и основных типов. Например, вы можете закодировать пару существующих терминов в лямбда-исчислении, используя ту же кодировку Черча, которую вы обычно видите для кодирования неотрицательных целых чисел и логического значения:
fst = λ p . p ( λ x y . x ) snd = λ p . p ( λ x y . y )
Тогда пара имеет вид p = ( пара a b ), и если вы хотите получить обратно a и b, вы можете выполнить ( fst p ) и ( snd p ) .
Это означает, что вы можете легко представлять положительные и отрицательные целые числа парой: знак слева и абсолютное значение справа. Знак должен быть логическим, который указывает, является ли число положительным. Право - это натуральное число с использованием церковного кодирования.
Чтобы определить сложение, вы должны сравнить два натуральных числа и использовать вычитание, когда знаки разные, так что это не λ-термин, но вы можете адаптировать его, если вы действительно хотите:
но тогда вычитание действительно легко определить: