Der 'algebraische' Ausdruck für algebraische Datentypen sieht für jemanden mit mathematischem Hintergrund sehr suggestiv aus. Lassen Sie mich versuchen zu erklären, was ich meine.
Nachdem Sie die Grundtypen definiert haben
- Produkt
•
- Union
+
- Singleton
X
- Einheit
1
und unter Verwendung der Kurzform X²
für X•X
und 2X
für X+X
usw. können wir dann algebraische Ausdrücke für z. B. verknüpfte Listen definieren
data List a = Nil | Cons a (List a)
↔ L = 1 + X • L
und binäre Bäume:
data Tree a = Nil | Branch a (Tree a) (Tree a)
↔ T = 1 + X • T²
Nun, mein erster Instinkt als Mathematiker gehen Nüsse mit dieser Ausdrücken und versuchen zu lösen L
und T
. Ich könnte dies durch wiederholte Substitution tun, aber es scheint viel einfacher zu sein, die Notation schrecklich zu missbrauchen und so zu tun, als könnte ich sie nach Belieben neu anordnen. Zum Beispiel für eine verknüpfte Liste:
L = 1 + X • L
(1 - X) • L = 1
L = 1 / (1 - X) = 1 + X + X² + X³ + ...
wo ich die Potenzreihenerweiterung von 1 / (1 - X)
auf völlig ungerechtfertigte Weise verwendet habe, um ein interessantes Ergebnis abzuleiten, nämlich dass ein L
Typ entweder Nil
ist oder 1 Element enthält oder 2 Elemente enthält oder 3 usw.
Es wird interessanter, wenn wir es für Binärbäume tun:
T = 1 + X • T²
X • T² - T + 1 = 0
T = (1 - √(1 - 4 • X)) / (2 • X)
T = 1 + X + 2 • X² + 5 • X³ + 14 • X⁴ + ...
wieder mit der Power Series-Erweiterung (mit Wolfram Alpha ). Dies drückt die für mich nicht offensichtliche Tatsache aus, dass es nur einen Binärbaum mit 1 Element, 2 Binärbäume mit zwei Elementen (das zweite Element kann sich auf dem linken oder rechten Zweig befinden), 5 Binärbäume mit drei Elementen usw. Gibt .
Meine Frage ist also - was mache ich hier? Diese Operationen scheinen ungerechtfertigt zu sein (was genau ist die Quadratwurzel eines algebraischen Datentyps?), Aber sie führen zu vernünftigen Ergebnissen. Hat der Quotient zweier algebraischer Datentypen in der Informatik eine Bedeutung oder handelt es sich nur um einen Trick der Notation?
Und, vielleicht interessanter, ist es möglich, diese Ideen zu erweitern? Gibt es eine Theorie der Typenalgebra, die beispielsweise beliebige Funktionen für Typen zulässt, oder erfordern Typen eine Potenzreihendarstellung? Wenn Sie eine Klasse von Funktionen definieren können, hat die Zusammensetzung von Funktionen dann eine Bedeutung?
quelle
Branch x (Branch y Nil Nil) Nil
oder es sieht so ausBranch x Nil (Branch y Nil Nil)
.undefined
,throw
usw. Wir sollten sie nutzen.Antworten:
Haftungsausschluss: Vieles davon funktioniert nicht ganz richtig, wenn Sie ⊥ berücksichtigen. Ich werde dies der Einfachheit halber offenkundig ignorieren.
Einige erste Punkte:
Beachten Sie, dass "Vereinigung" hier wahrscheinlich nicht der beste Begriff für A + B ist - dies ist speziell eine disjunkte Vereinigung der beiden Typen, da die beiden Seiten unterschieden werden, selbst wenn ihre Typen gleich sind. Für das, was es wert ist, ist der häufigere Begriff einfach "Summentyp".
Singleton-Typen sind praktisch alle Einheitentypen. Sie verhalten sich bei algebraischen Manipulationen identisch, und was noch wichtiger ist, die Menge der vorhandenen Informationen bleibt erhalten.
Sie möchten wahrscheinlich auch einen Nulltyp. Haskell bietet das als
Void
. Es gibt keine Werte, deren Typ Null ist, genauso wie es einen Wert gibt, dessen Typ Eins ist.Hier fehlt noch eine große Operation, aber ich werde gleich darauf zurückkommen.
Wie Sie wahrscheinlich bemerkt haben, neigt Haskell dazu, Konzepte aus der Kategorietheorie auszuleihen, und all das hat eine sehr einfache Interpretation als solche:
Bei gegebenen Objekten A und B in Hask ist ihr Produkt A × B der eindeutige Typ (bis zum Isomorphismus), der zwei Projektionen fst ermöglicht : A × B → A und snd : A × B → B, wobei ein beliebiger Typ C und Funktionen f gegeben sind : C → A, g : C → B Sie können die Paarung f &&& g : C → A × B so definieren, dass fst ∘ (f &&& g) = f und ebenfalls für g . Parametrizität garantiert die universellen Eigenschaften automatisch und meine weniger subtile Namenswahl sollte Ihnen die Idee geben. Der
(&&&)
Operator istControl.Arrow
übrigens in definiert.Das Doppelte der obigen ist das Nebenprodukt A + B mit Injektionen inl : A → A + B und inr : B → A + B, wobei jeder Typ C und jede Funktion f : A → C, g : B → C gegeben ist Definieren Sie die Copairing f ||| g : A + B → C, so dass die offensichtlichen Äquivalenzen gelten. Auch hier garantiert die Parametrizität die meisten kniffligen Teile automatisch. In diesem Fall sind die Standardinjektionen einfach
Left
undRight
und die Kopairing ist die Funktioneither
.Viele der Eigenschaften von Produkt- und Summentypen können aus den obigen abgeleitet werden. Beachten Sie, dass jeder Singleton-Typ ein Terminalobjekt von Hask ist und jeder leere Typ ein Anfangsobjekt.
Zurück zu der oben genannten fehlenden Operation: In einer kartesischen geschlossenen Kategorie haben Sie exponentielle Objekte , die Pfeilen der Kategorie entsprechen. Unsere Pfeile sind Funktionen, unsere Objekte sind Typen mit Art
*
, und der TypA -> B
verhält sich im Kontext der algebraischen Manipulation von Typen tatsächlich wie B A. Wenn es nicht offensichtlich ist, warum dies gelten sollte, ziehen Sie den Typ in BetrachtBool -> A
. Mit nur zwei möglichen Eingaben ist eine Funktion dieses Typs isomorph zu zwei Werten des TypsA
, d(A, A)
. H. DennMaybe Bool -> A
wir haben drei mögliche Eingaben und so weiter. Beachten Sie auch, dass wir die Identität C A × C B = C erhalten , wenn wir die obige Copairing-Definition umformulieren, um die algebraische Notation zu verwendenA + B .Was den Grund betrifft, warum dies alles sinnvoll ist - und insbesondere, warum Ihre Verwendung der Potenzreihenerweiterung gerechtfertigt ist -, beachten Sie, dass sich ein Großteil der oben genannten Punkte auf die "Einwohner" eines Typs (dh unterschiedliche Werte mit diesem Typ) in der Reihenfolge bezieht um das algebraische Verhalten zu demonstrieren. Um diese Perspektive deutlich zu machen:
Der Produkttyp
(A, B)
repräsentiert jeweils einen Wert vonA
undB
, unabhängig voneinander. Für jeden festen Werta :: A
gibt es also einen Typwert(A, B)
für jeden Einwohner vonB
. Dies ist natürlich das kartesische Produkt, und die Anzahl der Einwohner des Produkttyps ist das Produkt der Anzahl der Einwohner der Faktoren.Der Summentyp
Either A B
repräsentiert einen Wert von entwederA
oderB
, wobei der linke und der rechte Zweig unterschieden werden. Wie bereits erwähnt, handelt es sich um eine disjunkte Vereinigung, und die Anzahl der Einwohner des Summentyps ist die Summe der Anzahl der Einwohner der Summanden.Der Exponentialtyp
B -> A
repräsentiert eine Zuordnung von TypwertenB
zu TypwertenA
. Für jedes feste Argumentb :: B
kann ihm ein beliebiger Wert vonA
zugewiesen werden. Ein Wert vom TypB -> A
wählt für jede Eingabe eine solche Zuordnung aus, was einem Produkt von so vielen KopienA
wieB
Einwohner entspricht, daher die Potenzierung.Während es zunächst verlockend ist, Typen als Mengen zu behandeln, funktioniert dies in diesem Zusammenhang nicht sehr gut - wir haben eher eine disjunkte Vereinigung als die Standardvereinigung von Mengen, aber es gibt keine offensichtliche Interpretation von Schnittmengen oder vielen anderen Mengenoperationen, und wir Die festgelegte Mitgliedschaft ist normalerweise nicht wichtig (überlassen Sie dies der Typprüfung).
Andererseits verbringen die obigen Konstruktionen viel Zeit damit, über das Zählen von Einwohnern zu sprechen , und das Aufzählen der möglichen Werte eines Typs ist hier ein nützliches Konzept. Das führt uns schnell zu einer Aufzählungskombinatorik , und wenn Sie den verlinkten Wikipedia-Artikel konsultieren, werden Sie feststellen, dass eines der ersten Dinge darin besteht, "Paare" und "Gewerkschaften" im gleichen Sinne wie Produkt- und Summentypen zu definieren Wenn Sie Funktionen generieren , wird dies auch für "Sequenzen" ausgeführt, die mit Haskells Listen identisch sind, und zwar mit genau der gleichen Technik wie Sie.
Edit: Oh, und hier ist ein kurzer Bonus, der meiner Meinung nach den Punkt auffallend demonstriert. Sie haben in einem Kommentar erwähnt, dass Sie für einen
T = 1 + T^2
Baumtyp die Identität ableiten könnenT^6 = 1
, was eindeutig falsch ist. GiltT^7 = T
jedoch , und eine Bijektion zwischen Bäumen und sieben Tupeln von Bäumen kann direkt konstruiert werden, vgl. Andreas Blass '"Sieben Bäume in einem" .Bearbeiten × 2: Zum Thema der Konstruktion "Ableitung eines Typs", die in anderen Antworten erwähnt wird, könnte Ihnen auch dieses Papier desselben Autors gefallen, das weiter auf der Idee aufbaut, einschließlich der Begriffe der Teilung und anderer interessanter Dinge.
quelle
Binärbäume werden durch die Gleichung
T=1+XT^2
im Semiring von Typen definiert. KonstruktionsbedingtT=(1-sqrt(1-4X))/(2X)
wird durch die gleiche Gleichung beim Semiren komplexer Zahlen definiert. Angesichts der Tatsache, dass wir dieselbe Gleichung in derselben Klasse algebraischer Strukturen lösen, sollte es eigentlich nicht überraschen, dass wir einige Ähnlichkeiten sehen.Der Haken ist, dass wir, wenn wir über Polynome beim Semiren komplexer Zahlen nachdenken, normalerweise die Tatsache verwenden, dass die komplexen Zahlen einen Ring oder sogar ein Feld bilden, sodass wir Operationen wie Subtraktion verwenden, die nicht für Semiringe gelten. Aber wir können oft Subtraktionen von unseren Argumenten eliminieren, wenn wir eine Regel haben, die es uns erlaubt, von beiden Seiten einer Gleichung abzubrechen. Dies ist die Art von Dingen, die von Fiore und Leinster bewiesen wurden und die zeigen, dass viele Argumente über Ringe auf Semirings übertragen werden können.
Dies bedeutet, dass viele Ihrer mathematischen Kenntnisse über Ringe zuverlässig auf Typen übertragen werden können. Infolgedessen können einige Argumente mit komplexen Zahlen oder Potenzreihen (im Ring der formalen Potenzreihen) auf völlig strenge Weise auf Typen übertragen werden.
Die Geschichte enthält jedoch noch mehr. Es ist eine Sache, zu beweisen, dass zwei Typen gleich sind (sagen wir), indem gezeigt wird, dass zwei Potenzreihen gleich sind. Sie können jedoch auch Informationen zu Typen ableiten, indem Sie die Begriffe in der Potenzreihe überprüfen. Ich bin mir nicht sicher, wie die formelle Erklärung hier lauten soll. (Ich empfehle Brent Yorgey das Papier auf kombinatorische Art für einige Arbeit , die eng verwandt ist , aber Arten sind nicht die gleichen wie Typen.)
Was ich absolut umwerfend finde, ist, dass das, was Sie entdeckt haben, auf den Kalkül ausgedehnt werden kann. Theoreme über die Analysis können auf das Semiring von Typen übertragen werden. Tatsächlich können sogar Argumente über endliche Differenzen übertragen werden, und Sie stellen fest, dass klassische Theoreme aus der numerischen Analyse Interpretationen in der Typentheorie haben.
Habe Spaß!
quelle
P = X^2
hat eine AbleitungdP = X + X
, ebensoEither
wie der Ein-Loch-Kontext des Paares. Das ist ziemlich toll. Wir könnten uns integrieren,Either
um auch ein Paar zu bekommen. Aber wenn wir versuchen,Maybe
(mit TypM = 1 + X
) zu 'integrieren' , müssen wir haben,\int M = X + X^2 / 2
was unsinnig ist (was ist ein halber Typ?). Bedeutet dies, dass diesMaybe
nicht der Ein-Loch-Kontext eines anderen Typs ist?(A,A)
mit einem Loch darin ist einA
bisschen und sagt Ihnen ein wenig, auf welcher Seite sich das Loch befindet. EinA
Allein hat kein bestimmtes Loch zum Ausfüllen, weshalb Sie es nicht "integrieren" können. Die Art der fehlenden Informationen ist in diesem Fall natürlich2
.X^2/2
blog.sigfpe.com/2007/09/type-of-distinct-pairs.htmlEs scheint, dass Sie nur die Wiederholungsbeziehung erweitern.
Und da die Regeln für die Operationen für die Typen wie die Regeln für arithmetische Operationen funktionieren, können Sie algebraische Mittel verwenden, um herauszufinden, wie die Wiederholungsbeziehung erweitert werden kann (da dies nicht offensichtlich ist).
quelle
X
ein Element der reellen Zahlen ist, zu einer wahren Aussage über Typen übergehen und darüber hinaus, wo die Entsprechung (Koeffizient desn
Grad-Terms) <=> (Zahl) erfolgt Arten von Halteelementenn
) kommen von?T = 1 + T^2
kann ich aus dem Ausdruck für einen Baum ( ) ableitenT^6 = 1
(dh Lösungenx^2 - x + 1 = 0
sind sechste Wurzeln der Einheit), aber es ist eindeutig nicht wahr, dass ein Produkttyp, der aus sechs Binärbäumen besteht, der Einheit entspricht()
.T^7
undT
. vgl. arxiv.org/abs/math/9405205L = 1 + X * L
, sollte es daher die gleiche sein, die Sie erhalten, wenn Sie Serien erweitern, und zwar nach Konsistenz. Andernfalls könnten Sie das Ergebnis rückwärts ausführen, um etwas Falsches über die Reals zu erhalten.Ich habe keine vollständige Antwort, aber diese Manipulationen funktionieren normalerweise nur. Ein relevantes Papier könnten Objekte von Kategorien als komplexe Zahlen von Fiore und Leinster sein - ich bin auf dieses gestoßen, als ich den Blog von sigfpe zu einem verwandten Thema gelesen habe ; Der Rest dieses Blogs ist eine Goldmine für ähnliche Ideen und einen Besuch wert!
Sie können übrigens auch Datentypen unterscheiden - so erhalten Sie den passenden Reißverschluss für den Datentyp!
quelle
Die Algebra der kommunizierenden Prozesse (ACP) behandelt ähnliche Arten von Ausdrücken für Prozesse. Es bietet Addition und Multiplikation als Operatoren für Auswahl und Reihenfolge mit zugehörigen neutralen Elementen. Basierend auf diesen gibt es Operatoren für andere Konstrukte wie Parallelität und Störung. Siehe http://en.wikipedia.org/wiki/Algebra_of_Communicating_Processes . Es gibt auch ein Online-Papier mit dem Titel "Eine kurze Geschichte der Prozessalgebra".
Ich arbeite daran, Programmiersprachen mit ACP zu erweitern. Letzten April habe ich auf den Scala Days 2012 ein Forschungspapier vorgestellt, das unter http://code.google.com/p/subscript/ verfügbar ist.
Auf der Konferenz habe ich einen Debugger demonstriert, der eine parallele rekursive Spezifikation einer Tasche ausführt:
Tasche = A; (Tasche & a)
wobei A und a für Eingabe- und Ausgabeaktionen stehen; Das Semikolon und das kaufmännische Und stehen für Sequenz und Parallelität. Sehen Sie sich das Video bei SkillsMatter an, das über den vorherigen Link erreichbar ist.
Eine Taschenspezifikation, die vergleichbarer ist mit
L = 1 + X • L.
wäre
B = 1 + X & B.
ACP definiert Parallelität in Bezug auf Auswahl und Reihenfolge unter Verwendung von Axiomen; siehe den Wikipedia-Artikel. Ich frage mich, wofür die Taschenanalogie wäre
L = 1 / (1-X)
Die Programmierung im ACP-Stil ist praktisch für Textparser und GUI-Controller. Spezifikationen wie
searchCommand = geklickt (searchButton) + Taste (Enter)
cancelCommand = geklickt (cancelButton) + Taste (Escape)
kann präziser aufgeschrieben werden, indem die beiden Verfeinerungen "angeklickt" und "Schlüssel" implizit gemacht werden (wie es Scala mit Funktionen erlaubt). Daher können wir schreiben:
searchCommand = searchButton + Enter
cancelCommand = cancelButton + Escape
Die rechte Seite enthält jetzt Operanden, die Daten und keine Prozesse sind. Auf dieser Ebene ist es nicht erforderlich zu wissen, welche impliziten Verfeinerungen diese Operanden in Prozesse verwandeln. Sie würden sich nicht unbedingt zu Eingabeaktionen verfeinern. Ausgabeaktionen würden auch gelten, z. B. in der Spezifikation eines Testroboters.
Prozesse erhalten auf diese Weise Daten als Begleiter; daher präge ich den Begriff "Gegenstandsalgebra".
quelle
Kalkül- und Maclaurin-Reihen mit Typen
Hier ist eine weitere kleine Ergänzung - eine kombinatorische Einsicht, warum die Koeffizienten in einer Reihenexpansion "funktionieren" sollten, insbesondere mit Schwerpunkt auf Reihen, die unter Verwendung des Taylor-Maclaurin- Ansatzes aus der Analysis abgeleitet werden können. NB: Die Beispielserienerweiterung, die Sie für den manipulierten Listentyp angeben, ist eine Maclaurin-Serie.
Da sich andere Antworten und Kommentare mit dem Verhalten algebraischer Typausdrücke (Summen, Produkte und Exponenten) befassen, wird diese Antwort dieses Detail beseitigen und sich auf den Typ 'Kalkül' konzentrieren.
Möglicherweise stellen Sie in dieser Antwort fest, dass Anführungszeichen stark angehoben werden. Es gibt zwei Gründe:
Definition der Maclaurin-Reihe
Die Maclaurin-Reihe einer Funktion
f : ℝ → ℝ
ist definiert alswo
f⁽ⁿ⁾
bedeutet dien
th Ableitung vonf
.Um die Maclaurin-Reihe als mit Typen interpretiert zu verstehen, müssen wir verstehen, wie wir drei Dinge in einem Typkontext interpretieren können:
0
(1/n!)
und es stellt sich heraus, dass diese Konzepte aus der Analyse geeignete Gegenstücke in der Schriftwelt haben.
Was meine ich mit einem "geeigneten Gegenstück"? Es sollte den Geschmack eines Isomorphismus haben - wenn wir die Wahrheit in beide Richtungen bewahren können, können in einem Kontext ableitbare Tatsachen auf den anderen übertragen werden.
Kalkül mit Typen
Was bedeutet die Ableitung eines Typausdrucks? Es stellt sich heraus, dass es für eine große und gut erzogene ('differenzierbare') Klasse von Typausdrücken und Funktoren eine natürliche Operation gibt, die sich ähnlich genug verhält, um eine geeignete Interpretation zu sein!
Um die Pointe zu verderben, besteht die Operation analog zur Differenzierung darin, "Ein-Loch-Kontexte" zu erstellen. Dies ist ein ausgezeichneter Ort, um diesen bestimmten Punkt weiter zu erweitern, aber das Grundkonzept eines Ein-Loch-Kontexts (
da/dx
) besteht darin, dass es das Ergebnis des Extrahierens eines einzelnen Unterpunkts eines bestimmten Typs (x
) aus einem Begriff (des Typsa
) darstellt, wobei beibehalten wird alle anderen Informationen, einschließlich der Informationen, die zur Bestimmung des ursprünglichen Standorts des Unterelements erforderlich sind. Eine Möglichkeit, einen Ein-Loch-Kontext für eine Liste darzustellen, besteht beispielsweise aus zwei Listen: eine für Elemente, die vor der extrahierten kamen, und eine für Elemente, die danach kamen.Die Motivation, diesen Vorgang mit Differenzierung zu identifizieren, ergibt sich aus den folgenden Beobachtungen. Wir schreiben
da/dx
, um den Typ von Ein-Loch-Kontexten für Typa
mit Loch des Typs zu bezeichnenx
.Hier
1
und0
stellen Typen mit genau einer bzw. genau null Einwohner dar und+
und×
repräsentieren wie üblich Summen- und Produkttypen.f
undg
werden verwendet, um Typfunktionen oder Typausdrucksbildner darzustellen, und[f(x)/a]
bedeuten die Operation des Ersetzensf(x)
für jedena
im vorhergehenden Ausdruck.Dies kann in einem punktfreien Stil geschrieben werden
f'
, wobei die Ableitungsfunktion der Typfunktion bezeichnet wirdf
, also:was vorzuziehen sein kann.
Hinweis: Die Gleichungen können streng und genau gemacht werden, wenn wir Ableitungen unter Verwendung von Isomorphismusklassen von Typen und Funktoren definieren.
Nun stellen wir insbesondere fest, dass die Regeln im Kalkül, die sich auf die algebraischen Operationen Addition, Multiplikation und Zusammensetzung beziehen (oft als Summen-, Produkt- und Kettenregeln bezeichnet), sich genau in der Operation „Loch machen“ widerspiegeln. Darüber
x
hinaus verhalten sich die Basisfälle des "Machens eines Lochs" in einem konstanten Ausdruck oder der Begriff selbst auch als Differenzierung, sodass wir durch Induktion ein differenzierungsähnliches Verhalten für alle algebraischen Typausdrücke erhalten.Jetzt können wir die Differenzierung interpretieren. Was bedeutet die
n
Ableitung einesdⁿe/dxⁿ
Typausdrucks? Es ist ein Typ, dern
-place-Kontexte darstellt: Begriffe, die, wenn sie mitn
Begriffen des Typs 'gefüllt' sind,x
eine ergebene
. Es gibt eine weitere wichtige Beobachtung im Zusammenhang mit dem(1/n!)
späteren Kommen.Der invariante Teil eines Typfunktors: Anwenden einer Funktion auf 0
Wir haben bereits eine Interpretation für
0
in der Typwelt: einen leeren Typ ohne Mitglieder. Was bedeutet es aus kombinatorischer Sicht, eine Typfunktion darauf anzuwenden? Konkreter ausgedrückt: Angenommen, esf
handelt sich um eine Typfunktion. Wie sieht esf(0)
aus? Nun, wir haben sicherlich keinen Zugriff auf irgendetwas vom Typ0
, so dass Konstruktionen, fürf(x)
die ein erforderlichx
ist, nicht verfügbar sind. Was bleibt, sind jene Begriffe, die in ihrer Abwesenheit zugänglich sind und die wir als "invarianten" oder "konstanten" Teil des Typs bezeichnen können.Nehmen Sie als explizites Beispiel den
Maybe
Funktor, der algebraisch als dargestellt werden kannx ↦ 1 + x
. Wenn wir dies anwenden0
, erhalten wir1 + 0
- es ist nur so1
: Der einzig mögliche Wert ist derNone
Wert. In ähnlicher Weise erhalten wir für eine Liste nur den Begriff, der der leeren Liste entspricht.Wenn wir bringen sie zurück und interpretieren die Art
f(0)
als Nummer kann es als gedacht werden Zahl , wie viele nach Artf(x)
(für jedex
) ohne Zugriff auf eine erhalten werdenx
: die, die Zahl der ‚leer-like‘ Begriffe ist .Zusammenstellen: vollständige Interpretation einer Maclaurin-Serie
Ich fürchte, ich kann mir keine angemessene direkte Interpretation
(1/n!)
als Typ vorstellen.Wenn wir jedoch den Typ
f⁽ⁿ⁾(0)
im Lichte des obenn
Gesagten betrachten , sehen wir, dass er als Typ von Ortskontexten für einen Typbegriff interpretiert werden kann,f(x)
der noch keinx
- das heißt, wenn wir sien
mal 'integrieren' hat der resultierende Begriff genaun
x
s, nicht mehr und nicht weniger. Dann ist die Interpretation des Typsf⁽ⁿ⁾(0)
als Zahl (wie in den Koeffizienten der Maclaurin-Reihe vonf
) einfach eine Zählung der Anzahl solcher solcher Leerstellenkontexten
. Wir sind fast da!Aber wo landet
(1/n!)
es? Die Untersuchung des Prozesses der Typdifferenzierung zeigt, dass bei mehrmaliger Anwendung die Reihenfolge beibehalten wird, in der Subterme extrahiert werden. Betrachten Sie zum Beispiel den Begriff(x₀, x₁)
des Typsx × x
und die Operation, zweimal ein Loch darin zu machen. Wir bekommen beide Sequenzenobwohl beide vom selben Begriff stammen, weil es
2! = 2
Möglichkeiten gibt, zwei Elemente aus zwei zu nehmen und die Ordnung zu bewahren. Im Allgemeinen gibt esn!
Möglichkeiten,n
Elemente zu übernehmenn
. Um die Anzahl der Konfigurationen eines Funktortyps mitn
Elementen zu ermitteln, müssen wir den Typ zählenf⁽ⁿ⁾(0)
und durch dividierenn!
, genau wie bei den Koeffizienten der Maclaurin-Reihe.Das Teilen durch
n!
erweist sich also als einfach als sich selbst interpretierbar.Letzte Gedanken: 'rekursive' Definitionen und Analytizität
Zunächst einige Beobachtungen:
Da wir die Kettenregel haben, können wir implizite Differenzierung verwenden , wenn wir Typderivate als Isomorphismusklassen formalisieren. Die implizite Differenzierung erfordert jedoch keine außerirdischen Manöver wie Subtraktion oder Division! Wir können es also verwenden, um rekursive Typdefinitionen zu analysieren. Um Ihr Listenbeispiel zu nehmen, haben wir
und dann können wir auswerten
um den Koeffizienten von
X¹
in der Maclaurin-Reihe zu erhalten.Da wir jedoch zuversichtlich sind, dass diese Ausdrücke tatsächlich, wenn auch nur implizit, streng "differenzierbar" sind, und da wir die Entsprechung mit Funktionen ℝ → ℝ haben, bei denen Ableitungen sicherlich eindeutig sind, können wir sicher sein, dass selbst wenn wir die Werte mit 'erhalten. Bei illegalen Operationen ist das Ergebnis gültig.
Nun, in ähnlicher Weise, die zweite Beobachtung zu verwenden, aufgrund der Korrespondenz (es ist ein Homomorphismus?) Mit Funktionen r → r, wissen wir , dass, wenn wir überzeugt sind , dass eine Funktion hat eine Maclaurin Serie, wenn wir finden können jede Serie an Alles in allem können die oben beschriebenen Prinzipien angewendet werden, um es streng zu machen.
Was Ihre Frage zur Zusammensetzung von Funktionen betrifft, so gibt die Kettenregel vermutlich eine teilweise Antwort.
Ich bin nicht sicher, für wie viele ADTs im Haskell-Stil dies gilt, aber ich vermute, dass es viele, wenn nicht alle sind. Ich habe einen wirklich wunderbaren Beweis für diese Tatsache gefunden, aber dieser Rand ist zu klein, um ihn aufzunehmen ...
Dies ist sicherlich nur ein Weg, um herauszufinden, was hier vor sich geht, und es gibt wahrscheinlich viele andere Wege.
Zusammenfassung: TL; DR
0
Sie die "leeren" Begriffe für diesen Funktor.quelle
Abhängige Typentheorie und 'beliebige' Typfunktionen
Meine erste Antwort auf diese Frage war reich an Konzepten und wenig an Details und reflektierte die Unterfrage: "Was ist los?". Diese Antwort ist dieselbe, konzentriert sich jedoch auf die Unterfrage "Können wir beliebige Typfunktionen erhalten?".
Eine Erweiterung der algebraischen Operationen von Summen- und Produkt sind die sogenannten "großen Betreiber, die die Summe und Produkt einer Sequenz darstellen (oder allgemeiner, der Summe und Produkt einer Funktion über eine Domäne) in der Regel geschrieben
Σ
undΠ
jeweils. Siehe Sigma-Notation .Also die Summe
könnte geschrieben werden
Wo
a
ist zum Beispiel eine Folge von reellen Zahlen. Das Produkt würde ähnlich mitΠ
statt dargestelltΣ
.Wenn Sie aus der Ferne schauen, ähnelt diese Art von Ausdruck einer 'willkürlichen' Funktion in
X
; Wir beschränken uns natürlich auf ausdrucksstarke Reihen und die damit verbundenen analytischen Funktionen. Ist dies ein Kandidat für eine Darstellung in einer Typentheorie? Bestimmt!Die Klasse der Typentheorien, die diese Ausdrücke unmittelbar darstellen, ist die Klasse der 'abhängigen' Typentheorien: Theorien mit abhängigen Typen. Natürlich haben wir Begriffe, die von Begriffen abhängig sind, und in Sprachen wie Haskell mit Typfunktionen und Typquantifizierung, Begriffen und Typen, die von Typen abhängen. In einer abhängigen Einstellung haben wir zusätzlich Typen, die von Begriffen abhängen. Haskell ist keine abhängig typisierte Sprache, obwohl viele Merkmale abhängiger Typen simuliert werden können, indem die Sprache ein wenig gefoltert wird .
Curry-Howard und abhängige Typen
Der 'Curry-Howard-Isomorphismus' begann sein Leben als Beobachtung, dass die Begriffe und Typbeurteilungsregeln des einfach getippten Lambda-Kalküls genau der natürlichen Deduktion (wie von Gentzen formuliert) entsprechen, die auf die intuitionistische Aussagenlogik angewendet wird, wobei Typen die Sätze ersetzen und Begriffe, die den Platz von Beweisen einnehmen, obwohl die beiden unabhängig voneinander erfunden / entdeckt wurden. Seitdem ist es eine große Inspirationsquelle für Typentheoretiker. Eines der offensichtlichsten zu berücksichtigenden Dinge ist, ob und wie diese Entsprechung für die Aussagenlogik auf Prädikatenlogiken oder Logiken höherer Ordnung erweitert werden kann. Aus diesem Forschungsweg entstanden zunächst abhängige Typentheorien.
Eine Einführung in den Curry-Howard-Isomorphismus für einfach typisierte Lambda-Berechnungen finden Sie hier . Wenn wir zum Beispiel beweisen wollen,
A ∧ B
müssen wir beweisenA
und beweisenB
; Ein kombinierter Beweis ist einfach ein Beweispaar: einer für jede Konjunktion.In natürlicher Ableitung:
und in einfach getippter Lambda-Rechnung:
Ähnliche Entsprechungen existieren für
∨
und Summentypen→
und Funktionstypen und die verschiedenen Eliminierungsregeln.Ein unbeweisbarer (intuitionistisch falscher) Satz entspricht einem unbewohnten Typ.
Unter Berücksichtigung der Analogie von Typen als logische Sätze können wir uns überlegen, wie Prädikate in der Typwelt modelliert werden können. Es gibt viele Möglichkeiten, wie dies formalisiert wurde (siehe diese Einführung zu Martin-Löfs Intuitionistischer Typentheorie für einen weit verbreiteten Standard), aber der abstrakte Ansatz beobachtet normalerweise, dass ein Prädikat wie ein Satz mit Variablen für freie Begriffe oder alternativ wie ein Satz ist eine Funktion, die sich auf Sätze bezieht. Wenn wir zulassen, dass Typausdrücke Begriffe enthalten, bietet sich sofort eine Behandlung im Lambda-Kalkül-Stil an!
Was ist ein Beweis für nur konstruktive Beweise
∀x ∈ X.P(x)
? Wir können es uns als Beweisfunktion vorstellen, indem wir Begriffe (x
) für Beweise ihrer entsprechenden Sätze verwenden (P(x)
). So Mitglieder (Proofs) des Typs (Satz)∀x : X.P(x)
sind ‚abhängige Funktionen‘, die für jedenx
inX
einer Laufzeit von Art gebenP(x)
.Was ist mit
∃x ∈ X.P(x)
? Wir brauchen jedes MitgliedX
,x
zusammen mit einem BeweisP(x)
. Mitglieder (Beweise) des Typs (Satzes)∃x : X.P(x)
sind also 'abhängige Paare': ein definierter Begriffx
inX
, zusammen mit einem Begriff des TypsP(x)
.Notation: Ich werde verwenden
für tatsächliche Aussagen über Mitglieder der Klasse
X
, undfür Typausdrücke, die einer universellen Quantifizierung über Typ entsprechen
X
. Ebenso für∃
.Kombinatorische Überlegungen: Produkte und Summen
Neben der Curry-Howard-Entsprechung von Typen mit Sätzen haben wir die kombinatorische Entsprechung von algebraischen Typen mit Zahlen und Funktionen, was der Hauptpunkt dieser Frage ist. Glücklicherweise kann dies auf die oben beschriebenen abhängigen Typen erweitert werden!
Ich werde die Modulnotation verwenden
die 'Größe' eines Typs darstellen
A
, die in der Frage skizzierte Entsprechung zwischen Typen und Zahlen explizit machen. Beachten Sie, dass dies ein Konzept außerhalb der Theorie ist. Ich behaupte nicht, dass es einen solchen Operator in der Sprache geben muss.Zählen wir die möglichen (vollständig reduzierten, kanonischen) Mitglieder des Typs
Dies ist die Art von abhängigen Funktionen, die Begriffe
x
von TypX
zu Begriffen von Typ nehmenP(x)
. Jede solche Funktion muss für jeden Term eine Ausgabe habenX
, und diese Ausgabe muss von einem bestimmten Typ sein. Für jedenx
inX
, dann gibt dieser|P(x)|
‚Wahl‘ der Ausgabe.Die Pointe ist
Das macht natürlich keinen großen Sinn,
X
istIO ()
aber auf algebraische Typen anwendbar.Ebenso ein Begriff vom Typ
ist die Art der Paare
(x, p)
mitp : P(x)
, so gegebenen jedex
inX
können wir ein geeignetes Paar mit einem Mitglied des KonstruktsP(x)
, was|P(x)|
‚Auswahl‘.Daher,
mit den gleichen Einschränkungen.
Dies rechtfertigt die gemeinsame Notation für abhängige Typen in Theorien unter Verwendung der Symbole
Π
undΣ
, und tatsächlich verwischen viele Theorien die Unterscheidung zwischen "für alle" und "Produkt" und zwischen "es gibt" und "Summe" aufgrund der oben erwähnten Entsprechungen.Wir kommen näher!
Vektoren: Repräsentieren abhängiger Tupel
Können wir jetzt numerische Ausdrücke wie codieren?
als Typausdrücke?
Nicht ganz. Während wir informell die Bedeutung von Ausdrücken wie
Xⁿ
in Haskell betrachten können, woX
es sich um einen Typ undn
eine natürliche Zahl handelt, handelt es sich um einen Missbrauch der Notation. Dies ist ein Typausdruck, der eine Zahl enthält: eindeutig kein gültiger Ausdruck.Bei abhängigen Typen im Bild sind Typen mit Zahlen genau der Punkt. In der Tat sind abhängige Tupel oder 'Vektoren' ein sehr häufig genanntes Beispiel dafür, wie abhängige Typen pragmatische Sicherheit auf Typebene für Operationen wie den Listenzugriff bieten können . Ein Vektor ist nur eine Liste mit Informationen auf Typebene bezüglich seiner Länge: genau das, wonach wir für Typausdrücke wie suchen
Xⁿ
.Für die Dauer dieser Antwort lassen Sie
sein , die Art von längen-
n
VektorenX
; -Typ - Werten.Technisch gesehen ist
n
hier eher als eine tatsächliche natürliche Zahl eine Darstellung einer natürlichen Zahl im System. Wir können natürliche Zahlen (Nat
) im Peano-Stil entweder als Null (0
) oder als Nachfolger (S
) einer anderen natürlichen Zahl darstellen, undn ∈ ℕ
ich schreibe˻n˼
den Begriff, inNat
dem dargestellt wirdn
. Zum Beispiel˻3˼
istS (S (S 0))
.Dann haben wir
für jeden
n ∈ ℕ
.Nat-Typen: Förderung von ℕ Begriffen zu Typen
Jetzt können wir Ausdrücke wie codieren
als Typen. Dieser spezielle Ausdruck würde zu einem Typ führen, der natürlich isomorph zu dem Typ von Listen von ist
X
, wie in der Frage angegeben. (Nicht nur das, sondern aus kategorietheoretischer Sicht ist die Typfunktion - die ein Funktor ist -,X
die den obigen Typ übernimmt , natürlich isomorph zum Listenfunktor.)Ein letztes Puzzleteil für 'beliebige' Funktionen ist das Codieren, z
Ausdrücke wie
damit wir beliebige Koeffizienten auf eine Potenzreihe anwenden können.
Wir verstehen bereits die Entsprechung algebraischer Typen mit Zahlen, sodass wir von Typen zu Zahlen und von Typfunktionen zu numerischen Funktionen abbilden können. Wir können auch den anderen Weg gehen! - Wenn man eine natürliche Zahl nimmt, gibt es offensichtlich einen definierbaren algebraischen Typ mit so vielen Termmitgliedern, unabhängig davon, ob wir abhängige Typen haben oder nicht. Wir können dies leicht außerhalb der Typentheorie durch Induktion beweisen . Was wir brauchen, ist eine Möglichkeit, innerhalb des Systems von natürlichen Zahlen auf Typen abzubilden .
Eine erfreuliche Erkenntnis ist, dass, sobald wir abhängige Typen haben, der Beweis durch Induktion und die Konstruktion durch Rekursion sehr ähnlich werden - tatsächlich sind sie in vielen Theorien dasselbe. Sollten wir sie nicht konstruieren können, da wir durch Induktion beweisen können, dass Typen existieren, die unsere Bedürfnisse erfüllen?
Es gibt verschiedene Möglichkeiten, Typen auf Begriffebene darzustellen. Ich werde hier eine imaginäre Haskellish-Notation mit
*
für das Universum der Typen verwenden, die normalerweise selbst als Typ in einer abhängigen Umgebung betrachtet wird. 1Ebenso gibt es mindestens so viele Möglichkeiten, "
ℕ
-elimination" zu notieren , wie es abhängige Typentheorien gibt. Ich werde eine Haskellish Pattern Matching Notation verwenden.Wir brauchen eine Zuordnung
α
vonNat
bis*
zur EigenschaftDie folgende Pseudodefinition reicht aus.
Wir sehen also, dass die Wirkung von
α
das Verhalten des NachfolgersS
widerspiegelt und es zu einer Art Homomorphismus macht.Successor
ist eine Typfunktion, die der Anzahl der Mitglieder eines Typs 'eins' hinzufügt; das heißt,|Successor a| = 1 + |a|
für allea
mit einer definierten Größe.Zum Beispiel
α ˻4˼
(was istα (S (S (S (S 0))))
), istund die Begriffe dieses Typs sind
Geben Sie uns genau vier Elemente :
|α ˻4˼| = 4
.Ebenso
n ∈ ℕ
haben wir für jedennach Bedarf.
*
lediglich Repräsentanten von Typen sind, und eine Operation wird als explizite Zuordnung von Typbegriffen*
zu den zugehörigen Typen bereitgestellt . Andere Theorien erlauben es den Literaltypen selbst, Entitäten auf Termebene zu sein."Beliebige" Funktionen?
Jetzt haben wir den Apparat, eine vollständig allgemeine Potenzreihe als Typ auszudrücken!
Die Serie
wird zum Typ
Wo
˻f˼ : Nat → Nat
ist eine geeignete Darstellung in der Sprache der Funktionf
. Wir können dies wie folgt sehen.Wie "willkürlich" ist das? Wir beschränken uns bei dieser Methode nicht nur auf ganzzahlige Koeffizienten, sondern auch auf natürliche Zahlen. Abgesehen
f
davon kann bei einer Turing Complete- Sprache mit abhängigen Typen alles möglich sein, und wir können jede analytische Funktion mit natürlichen Zahlenkoeffizienten darstellen.Ich habe die Wechselwirkung davon zum Beispiel mit dem Fall nicht untersucht, der in der Frage angegeben wurde,
List X ≅ 1/(1 - X)
oder welchen möglichen Sinn solche negativen und nicht ganzzahligen "Typen" in diesem Zusammenhang haben könnten.Hoffentlich hilft diese Antwort dabei, herauszufinden, wie weit wir mit Funktionen beliebigen Typs gehen können.
quelle