Respuestas:
Primero codifique números y pares naturales, como lo describe jmad.
Representa un número entero como un par de números naturales tal que . Luego puede definir las operaciones habituales en enteros como (usando la notación de Haskell para cálculo ):
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)
El caso de los números complejos es similar en el sentido de que un número complejo está codificado como un par de reales. Pero una pregunta más complicada es cómo codificar los reales. Aquí tienes que hacer más trabajo:
Codificar reales es mucho trabajo y no quieres hacerlo en el cálculo . Pero vea, por ejemplo, el subdirectorio de Marshall para una implementación simple de reales en Haskell puro. En principio, esto podría traducirse al cálculo λ puro .etc/haskell
i:ℤ
, x:a
, f,u,s:a→a
, p:(a→a,a→a)
] Si codifican ℤ como (Sign,ℕ)
entonces, dado un par de funciones (s,f)
como p
, el término λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)
producirá ya sea f(…f(x)…)
o s(f(…f(x)…))
(si el resultado es negativo). Si codifica ℤ como (ℕ,ℕ)
, necesita una función que tenga un inverso, dado un par (f,u)
y x
, la función λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)
producirá u(…u(f(…f(x)…))…)
lo que dejará los tiempos f
aplicados . Ambos funcionan en diferentes contextos (el resultado puede "voltearse" || es invertible). i
x
f
fold . ctor
para cualquier constructor y ese tipo fold
( r
). (Es por eso que, para los tipos recursivos, los datos "recurrirán por sí mismos". Para los tipos no recursivos es más como una case
coincidencia de patrón /.)
El cálculo Lambda puede codificar la mayoría de las estructuras de datos y tipos básicos. Por ejemplo, puede codificar un par de términos existentes en el cálculo lambda, utilizando la misma codificación de Church que suele ver para codificar enteros no negativos y booleanos:
fst = λ p . p ( λ x y . x ) snd = λ p . p ( λ x y . y )
Entonces el par es p = ( emparejar un b ) y si quieres volver una y b se puede hacer ( FST p ) y ( SND p ) .
Eso significa que puede representar fácilmente enteros positivos y negativos con un par: el signo a la izquierda y el valor absoluto a la derecha. El signo es un booleano que especifica si el número es positivo. El derecho es un número natural que usa la codificación de Church.
Y ahora que tienes enteros relativos. La multiplicación es fácil de definir, solo tiene que aplicar la función en el signo y la multiplicación en números naturales en el valor absoluto:
Para definir la suma, debe comparar dos números naturales y usar la resta cuando los signos son diferentes, por lo que este no es un término λ pero puede adaptarlo si realmente desea:
pero luego la resta es realmente fácil de definir: