fckertube.com

  

Beste Artikel:

  
Main / Curry Howard Scala grün

Curry Howard Scala grün

Was ist ein Gewerkschaftstyp? Die Werte dieses Vereinigungstyps sind alle Werte vom Typ Int und alle Werte vom Typ String.

Was bedeutet das konkreter? Es bedeutet, dass wir schreiben könnten, wenn wir diesen Typ direkt in Scala ausdrücken könnten. Mit anderen Worten, die Größenmethode würde Argumente vom Typ Int oder vom Typ String und deren Untertypen Null und Nichts und sonst nichts akzeptieren.

Neufassung unseres Beispiels in Bezug auf Entweder wir bekommen. Genauso klar verwaltet der Typ "Beides" dies über eine Ebene der Boxdarstellung, anstatt ein primitives Merkmal des Typsystems ohne Box zu sein.

Können wir es besser machen als beide? Es stellt sich heraus, dass wir es können, aber um dorthin zu gelangen, müssen wir über den Curry-Howard-Isomorphismus einen Umweg durch die Logik erster Ordnung machen. Curry-Howard sagt uns, dass die Beziehungen zwischen Typen in einem Typsystem als Bild der Beziehungen zwischen Sätzen in einem logischen System angesehen werden können und umgekehrt. Die Essenz von Curry-Howard ist, dass dieser mechanische Umschreibungsprozess, egal in welche Richtung Sie gehen, immer die Gültigkeit bewahrt - gültige Typformeln werden immer in gültige logische Formeln umgeschrieben und umgekehrt.

Wir können auch die Entsprechung zu logischen Formeln verallgemeinern, zu denen die Negation, die für uns hier der Schlüssel ist, und die universelle und existenzielle Quantifizierung gehören. Was würde es also bedeuten, der Mischung Negation hinzuzufügen? Die Verbindung von zwei Typen, dh. Können wir also die Typennegation ausdrücken? Was wir aber tun können, ist, alle unsere Typen so zu transformieren, dass die Negation im transformierten Kontext ausgedrückt werden kann.

Einige Leser waren vielleicht etwas überrascht, als ich Curry-Howard mit Schnittpunkttypen als Korrelat der Konjunktion, Vereinigungstypen als Korrelat der Disjunktion und der Subtypbeziehung als Korrelat der Implikation illustrierte. A, B Modellkonjunktion, Summentypen dh. Entweder [A, B] Modelldisjunktion oder Funktionstypen Modellimplikation. Wenn wir unsere frühere Tabelle in Bezug auf Produkte, Summen und Funktionen neu formulieren, erhalten wir dies.

Dies ist die Form, in der der Curry-Howard-Isomorphismus typischerweise für Sprachen ohne Subtypisierung ausgedrückt wird. Aber es kann uns bei der Verneinung helfen, was das fehlende Stück ist, das wir brauchen. Jetzt müssen wir darüber nachdenken, wie eine Funktionssignatur aussieht. Dies bedeutet, dass der Vereinigungstyp selbst ein Funktionstyp ist. Was könnte diese Transformation sein?

Wie wäre es mit doppelter Verneinung? Ein letzter kleiner Trick, um dies ein wenig zu verfeinern. Der implizite Evidence-Parameter ist syntaktisch etwas hässlich und schwergewichtig, und wir können die Dinge ein wenig verbessern, indem wir ihn in einen Kontext konvertieren, der wie folgt an den Typparameter T gebunden ist.

Und da haben Sie es - eine unverpackte, statisch typsichere Codierung von Unionstypen in unverändertem Scala! Natürlich wäre es schöner, wenn Scala Unionstypen als Grundelemente unterstützen würde, aber zumindest zeigt diese Konstruktion, dass der Scala-Compiler über alle Informationen verfügt, die er dazu benötigt. Jetzt müssen wir nur noch Martin und Adriaan belästigen, um es direkt zugänglich zu machen. So können Sie dies insbesondere definieren.

Wenn Sie jedoch versuchen, die Größe eines Strings zu ermitteln, wird eine Fehlermeldung angezeigt, und auf den Double-Fall der Übereinstimmung kann nicht zugegriffen werden. Sowohl das Ergebnis als auch der Weg und die Erklärung. Es vermeidet die Verwendung von Reflexion, um dem Typ im Hauptteil der Funktion zu entsprechen, und ist auch leichter auf mehr als 2 Typen erweiterbar. Vielleicht ist dies ein Compiler-Fehler? Adriaan würde es wissen.

Ich versuche es nur ein bisschen voranzutreiben, aber ich habe ein seltsames Problem gefunden und kann nicht herausfinden, was ich falsch mache. Ich habe eine solche Funktion definiert: T wurde im zweiten Parameterblock als Int abgeleitet, sodass der String-Fall vom Compiler korrekt als nie zutreffend zurückgewiesen wird.

Siehe meine Antwort an hseeberger für das Problem der Einschränkung des Typs innerhalb des Körpers. Vielen Dank für Ihre schnelle Antwort Miles, jetzt sehe ich meinen Fehler. Glauben Sie, dass es eine Möglichkeit gibt, Unionstypen als Parameter einer Funktion höherer Ordnung wie in meinem Beispiel zu verwenden? Ich kann nicht finden wie. Bei der Codierung wird ein Argument vom Typ Union in ein Argument vom Typ Parameter mit einer Einschränkung umgewandelt. Über Entweder: Anstatt das Argument vom Typ Entweder zu machen, können Sie definieren, dass es als Entweder angezeigt werden kann. Wenn Sie die impliziten Konvertierungen im Gültigkeitsbereich angeben, können Sie das Boxen vermeiden, da nur T in Beides konvertiert werden kann.

Siehe hier. Darüber hinaus können Sie den Parameter mithilfe des Typs Oder oder Entweder für die spätere Verwendung speichern. Ja, das funktioniert auch. Das Prinzip der Verwendung von Phantomtypen In Ihrem Fall ist es sehr leistungsfähig, einem Basistyp Typeinschränkungen aufzuerlegen. Schauen Sie sich den generierten Bytecode an und Sie können sehen, dass er auf ev angewendet wird. Aber warte, wie kommt es, dass du die doppelte Negation in den Curry-Howard-Isomorphismus wirfst? Doppelte Negation ist keine Identität in einer intuitionistischen Logik; Sie können sich also nicht ernsthaft darauf verlassen, die Gesetze von de Morgan anzuwenden.

Ich glaube. Es gibt jedoch vorläufige Pläne, den impliziten Lösungsmechanismus in einer zukünftigen Version von Scala aufzudecken, die dies ermöglichen würde - mit dem derzeit auf dem Tisch liegenden Vorschlag würde er ungefähr so ​​aussehen.

Das heißt, bis dies in einer veröffentlichten Version von Scala eintrifft, könnten wir ohnehin erstklassige Gewerkschaftstypen in der Sprache haben. Das wäre schön, wenn man bedenkt, dass mich die Inspiration für diesen Beitrag beeindruckt hat, als ich Geoffrey Washburns Artikel über die Codierung höherrangiger Typen in Scala erneut las, in dem auch eine doppelte Negationscodierung verwendet wird, obwohl sie sehr unterschiedlich ausgedrückt wird, wobei Fortsetzungen verwendet werden.

Das ist schön, aber ich denke, Ihre Erklärung betont den Isomorphismus zu sehr oder bietet ein zu begrenztes Codierungsschema, um wirklich mit dem Isomorphismus übereinzustimmen. Es gibt eine einfachere Erklärung dafür, warum das Schema funktioniert, nämlich dass das Argument einer Funktion kontravariant ist.

Nun seien A und B ein beliebiges Typenpaar. Z [A mit B]. Die Howard-Curry-Isomorphismus-Codierung ist zwar wahr, aber so etwas wie ein roter Hering, da Sie die Typnegation nicht auf brauchbare Weise, zumindest nicht einfach, AFAICT-codieren können. So zum Beispiel f Einige 5: Jeder kommt am Compiler vorbei, was den Zweck zunichte macht. Guter Punkt. Also ziehe ich meinen ursprünglichen Kommentar zurück: Angesichts des Vereinigungstyps müssen wir Musterübereinstimmungen durchführen, und angesichts der Überladung müssen wir dynamisch versenden.

Man könnte sagen, dass Überladung kleinere Funktionen ermöglicht, aber vielleicht bieten Gewerkschaften die Möglichkeit für umfassende Compiler-Überprüfungen der Musterübereinstimmung? Oh, verdammt noch mal, kratzen Sie diese Frage…: Soll das immer noch funktionieren, wenn Sie Type Union als generische Parameter für Sammlungen verwenden? Insbesondere, dass A keine Funktion ist? Etwas wie:. Der Punkt des Artikels ist zu zeigen, dass wir Unionstypen ohne Boxen codieren können.

Vielleicht fehlt mir auch etwas, aber es scheint, dass es einige Verbesserungen gegenüber Entweder gibt. Vielleicht wäre es besser, V anstelle von Or zu verwenden, z. IntVString oder Int v String? Okay, entschuldige. In meinen Augen ist es für alle praktischen Zwecke eine Unboxed-Lösung, da das Boxen und Unboxing implizit ist und möglicherweise weg optimiert wird. Aber ich kann Ihren Standpunkt auch zu schätzen wissen, und es gibt möglicherweise weitere Eckfälle zusätzlich zu denen, die ich mit meiner Methode lauerte?

Vielen Dank, dass Sie meine Kommentare akzeptiert haben, obwohl sie nicht zum Thema gehören. Ich habe mich gefragt, ob man das auf n-ary Gewerkschaften verallgemeinern kann. Nur um die Diskussion mit Rex Kerr zu verstehen - dieser Code scheint ohne Probleme zu funktionieren, und Sie haben sich anscheinend bereits darauf geeinigt, oder? Was sind die Laufzeitkosten für die Erstellung und Übergabe all dieser Proof-Begriffe?

Bei der Implementierung von Sprachen mit abhängiger Typisierung arbeiten die Menschen hart daran, alle zu löschen. Aus der Literatur geht implizit hervor, dass das Nichtlöschen ein erhebliches Problem darstellt, und es klingt durchaus vernünftig. Eine Korrektur: List [Int] erzeugt eine Umwandlung in Int. Da sich die Umwandlung im Aufrufer befindet, sollte das Entfernen des Funktionsaufrufs nach dem Einfügen der Umwandlung kein Problem sein. Negation der Disjunktion i.

Beachten Sie, dass ich dies für ein Kung Fu mit abhängiger Eingabe benötigte, bei dem ich die Schlüssel einer Hash-Map statisch eingebe und zur Kompilierungszeit statisch doppelte Operationen innerhalb jeder Ereignishandlerfunktion auf der Hash-Map des Statusobjekts verhindern möchte.

Shelby, interessant aussehendes Zeug! Möglicherweise interessieren Sie sich auch für die abhängig typisierte Codierung erweiterbarer Datensätze in Shapeless.

Dies wird nicht direkt funktionieren, dies wird nicht kompiliert. Das heißt, wenn wir diesen Typ direkt in Scala ausdrücken könnten, könnten wir schreiben, def size x: T implizit ev: Max Bolingbroke mbolingbroke - Do, 9. Juni 2011, 3: Insbesondere können Sie diese def size definieren [ T] t: Heiko Seeberger hseeberger - Do, 9. Juni 2011, 6:

(с) 2019 fckertube.com