Die meisten Tutorials zu Lambda Calculus bieten Beispiele, in denen positive Ganzzahlen und Boolesche Werte durch Funktionen dargestellt werden können. Was ist mit -1 und ich?
Die meisten Tutorials zu Lambda Calculus bieten Beispiele, in denen positive Ganzzahlen und Boolesche Werte durch Funktionen dargestellt werden können. Was ist mit -1 und ich?
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)
wiep
der Begriffλi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)
produziert entwederf(…f(x)…)
oders(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)
undx
die Funktionλi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)
wird erzeugen,u(…u(f(…f(x)…))…)
was dief
angewendeteni
Zeiten belässtx
. Beide arbeiten in unterschiedlichen Kontexten (Ergebnis kann "gespiegelt" werden ||f
ist invertierbar).fold . ctor
für jeden Konstrukteur und diese Art derfold
(r
). (Aus diesem Grund werden die Daten bei rekursiven Typen "von selbst rekursiv". Bei nicht rekursiven Typen handelt es sich eher um einecase
/ 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 ) .(a,b) p=(pair ab) a b (fst p) (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(a,b) which represents a+bi . Then addition is point-wise and multiplication is as usual, but I won't write it, it should be easy:
quelle