Respostas:
Primeiro codifique números e pares naturais, conforme descrito por jmad.
Represente um número inteiro como um par de números naturais tal que . Em seguida, você pode definir as operações usuais em números inteiros como (usando a notação Haskell para -calculus):( 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)
O caso de números complexos é semelhante no sentido em que um número complexo é codificado como um par de reais. Mas uma pergunta mais complicada é como codificar reais. Aqui você tem que fazer mais trabalho:
Codificar reais é muito trabalhoso e você não deseja realmente fazê-lo no -calculus. Mas veja, por exemplo, o subdiretório Marshall, para uma simples implementação de reais em puro Haskell. Isso poderia, em princípio, ser traduzido para o λ- cálcio puro .etc/haskell
i:ℤ
, x:a
, f,u,s:a→a
, p:(a→a,a→a)
] Se codificar ℤ como (Sign,ℕ)
em seguida, dado um par de funções (s,f)
como p
, o termo λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)
irão produzir tanto f(…f(x)…)
ou s(f(…f(x)…))
(se o resultado for negativo). Se você codificar ℤ como (ℕ,ℕ)
, precisará de uma função que tenha um inverso - dado um par (f,u)
e x
, a função λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)
produzirá a u(…u(f(…f(x)…))…)
qual deixará os tempos f
aplicados . Ambos funcionam em contextos diferentes (o resultado pode ser "invertido" || é invertível). i
x
f
fold . ctor
para qualquer construtor e esse tipo fold
( r
). (É por isso que, para os tipos de recursiva, os dados serão "recurse por conta própria" Para os tipos não-recursiva é mais como um. case
/ Correspondência de padrão.)
O cálculo lambda pode codificar a maioria das estruturas de dados e tipos básicos. Por exemplo, você pode codificar um par de termos existentes no cálculo lambda, usando a mesma codificação da Igreja que você normalmente vê para codificar números inteiros não negativos e booleanos:
fst = λ p . p ( λ x y . x ) snd = λ p . p ( λ x y . y )
Em seguida, o par é p = ( emparelhar um b ) e se você quiser voltar a e b que você pode fazer ( FST p ) e ( SND p ) .
Isso significa que você pode facilmente representar números inteiros positivos e negativos com um par: o sinal à esquerda e o valor absoluto à direita. O sinal é um booleano que especifica se o número é positivo. O direito é um número natural usando a codificação da Igreja.
E agora que você tem números inteiros relativos. A multiplicação é fácil de definir, basta aplicar a função no sinal e a multiplicação em números naturais no valor absoluto:
Para definir a adição, você deve comparar dois números naturais e usar subtração quando os sinais forem diferentes; portanto, esse não é um termo λ, mas você pode adaptá-lo se realmente quiser:
mas a subtração é realmente fácil de definir: