Antworten:
Kodieren Sie zunächst natürliche Zahlen und Paare, wie von jmad beschrieben.
Stellen Sie eine ganze Zahl als ein Paar natürlicher Zahlen ( a , b ) dar, so dass k = a - b . Dann können Sie die üblichen Operationen für ganze Zahlen wie folgt definieren (unter Verwendung der Haskell-Notation für λ- Kalkül):
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)
Der Fall komplexer Zahlen ist in dem Sinne ähnlich, dass eine komplexe Zahl als ein Paar von Real codiert wird. Eine kompliziertere Frage ist jedoch, wie man reelle Zahlen codiert. Hier muss man mehr arbeiten:
Das Codieren von Real ist eine Menge Arbeit und Sie möchten es nicht wirklich im Kalkül tun. Schauen Sie sich zum Beispiel das Unterverzeichnis von Marshall an, um eine einfache Implementierung von Real in pure Haskell zu erhalten. Dies könnte prinzipiell auf den reinen λ- Kalkül übertragen werden.etc/haskell
i:ℤ
, x:a
, f,u,s:a→a
, p:(a→a,a→a)
] Wenn Sie kodieren z als (Sign,ℕ)
dann, da ein Paar von Funktionen (s,f)
wie p
der Begriff λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)
produziert entweder f(…f(x)…)
oder s(f(…f(x)…))
(wenn das Ergebnis negativ ist ). Wenn Sie ℤ as codieren (ℕ,ℕ)
, benötigen Sie eine Funktion, die ein inverses gegebenes Paar hat, (f,u)
und x
die Funktion λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)
wird erzeugen, u(…u(f(…f(x)…))…)
was die f
angewendeten i
Zeiten belässt x
. Beide arbeiten in unterschiedlichen Kontexten (Ergebnis kann "gespiegelt" werden || f
ist invertierbar).
fold . ctor
für jeden Konstrukteur und diese Art der fold
( r
). (Aus diesem Grund werden die Daten bei rekursiven Typen "von selbst rekursiv". Bei nicht rekursiven Typen handelt es sich eher um eine case
/ pattern-Übereinstimmung.)
Lambda-Kalkül kann die meisten Datenstrukturen und Grundtypen codieren. Sie können beispielsweise ein Paar vorhandener Terme im Lambda-Kalkül codieren, indem Sie dieselbe Church-Codierung verwenden, mit der Sie normalerweise nichtnegative Ganzzahlen und Boolesche Werte codieren:
fst = λ p . p ( λ x y . x ) snd = λ p . p ( λ x y . y )
Dann wird das Paar ist p = ( Pairing ein b ) und wenn Sie möchten , um wieder ein und b können Sie tun ( fst p ) und ( snd p ) .
Das bedeutet, dass Sie positive und negative ganze Zahlen mit einem Paar leicht darstellen können: das Vorzeichen links und den absoluten Wert rechts. Das Vorzeichen ist ein Boolescher Wert, der angibt, ob die Zahl positiv ist. Das Recht ist eine natürliche Zahl, die die Kodierung der Kirche verwendet.
Um die Addition zu definieren, müssen Sie zwei natürliche Zahlen vergleichen und Subtraktion verwenden, wenn sich die Vorzeichen unterscheiden. Dies ist also kein λ-Term, aber Sie können ihn anpassen, wenn Sie wirklich wollen:
but then subtraction is really easy to define:
Once you have positive and negative integers you can define complex integers very easily: it is just a pair of two integers which represents . Then addition is point-wise and multiplication is as usual, but I won't write it, it should be easy: