dependent-type

___ qstnhdr ___ Gibt es Vorteile von starker Typisierung neben Sicherheit? ___ answer36143094 ___

Refactoring. Mit einem starken Typsystem können Sie Code sicher umgestalten und der Compiler Ihnen mitteilen, ob das, was Sie gerade tun, jetzt sogar Sinn macht. Je stärker das Typisierungssystem, desto mehr Refactor-Fehler werden vermieden. Dies bedeutet natürlich, dass Ihr Code viel wartbarer ist.

    
___ answer36145400 ___

Zuerst müssen wir ein wenig über die Geschichte des einfach typisierten Lambda-Kalküls sprechen.

Es gibt zwei historische Entwicklungen des einfach typisierten Lambda-Kalküls.

  • Als Alonzo Church den Lambda-Kalkül beschrieb, wurden die Typen als Teil des Bedeutungs- / Betriebsverhaltens der Begriffe gebacken.

  • Als Haskell Curry den Lambda-Kalkül beschrieb, waren die Typen Anmerkungen zu den Begriffen.

Also haben wir den Lambda-Kalkül a la Church und den Lambda-Kalkül a la Curry. Siehe Ссылка für mehr.

Ironischerweise basiert die Sprache Haskell, die nach Curry benannt ist, auf einem Lambda-Kalkül a la Church!

Was das bedeutet, sind die Typen nicht einfach Annotationen, die schlechte Programme für Sie ausschließen. Sie können auch "Sachen machen". Solche Typen löschen nicht, ohne Rückstände zu hinterlassen.

Das zeigt sich in Haskells Vorstellung von Typenklassen, und das ist der Grund, warum Haskell eine Sprache a la Kirche ist.

In Haskell, wenn ich eine Funktion mache

%Vor%

Wir übergeben ein Objekt oder ein Wörterbuch für %code% als erstes Argument.

Aber Sie sind nicht gezwungen, dieses Argument um sich herum im Code auszuloten, es ist die Aufgabe des Compilers, das aufzubauen und zu benutzen.

%Vor%

Wenn Sie also eine Liste von Strings sortieren, die selbst Listen von Zeichen sind, dann baut dies das Wörterbuch auf, indem es die Ord Char-Instanz durch die Instanz für Ord a = & gt; Ord [a], um Ord [Char] zu erhalten, was dasselbe wie Ord String ist, dann können Sie eine Liste von Strings sortieren.

Der Aufruf von %code% oben ist viel weniger ausführlich als das manuelle Erstellen eines %code% , indem Sie ihm einen %code% an seinen Konstruktor übergeben und die Funktion mit einem zusätzlichen zweiten Argument aufrufen, wenn ich die Komplexität des Aufrufs vergleichen sollte eine solche %code% -Funktion in Haskell, um sie in C # oder Java aufzurufen.

Dies zeigt uns, dass die Programmierung mit Typen wesentlich weniger ausführlich sein kann, weil Mechanismen wie implicits und typeclasses einen großen Teil des Codes für Ihr Programm während der Typprüfung ableiten können.

Auf einer einfacheren Basis können sogar die Größen von Argumenten von Typen abhängen, es sei denn, Sie wollen ziemlich hohe Kosten dafür bezahlen, alles in Ihrer Sprache zu verpacken, so dass es eine homogene Darstellung hat.

Dies zeigt uns, dass das Programmieren mit Typen wesentlich effizienter sein kann, da es dedizierte Darstellungen verwenden kann, anstatt überall in Ihrem Code geboxte Strukturen zu bezahlen. Ein %code% kann nicht einfach eine Maschinen-Ganzzahl sein, weil es irgendwie wie alles andere im System aussehen muss. Wenn Sie bereit sind, zur Laufzeit eine Größenordnung oder mehr Leistung aufzugeben, ist dies für Sie nicht von Bedeutung.

Schließlich, wenn wir Typen haben, die "Dinge tun" für uns, ist es oft vorteilhaft, die Refactoring-Vorteile zu berücksichtigen, die reine Sicherheit bietet.

Wenn ich den kleineren Satz Code, der übrig bleibt, umgestalte, schreibt er alle diese Klöster der Typklasse für mich neu. Es wird herausfinden, wie es den Code neu schreiben kann, um mehr Argumente zu entpacken. Ich bin nicht damit beschäftigt, all diese Dinge mit der Hand auszuarbeiten, ich kann diese alltäglichen Aufgaben dem Typ-Checker überlassen.

Aber selbst wenn ich die Typen ändere, kann ich argwöhnisch Argumente umherbewegen, angenehm, dass der Compiler sehr wahrscheinlich meine Fehler fängt. Typen geben Ihnen "freie Sätze", die wie Unit-Tests für ganze Klassen solcher Fehler sind.

Auf der anderen Seite, sobald ich eine API in einer Sprache wie Python gesperrt habe, habe ich Todesangst davor, sie zu ändern, weil sie zur Laufzeit stillschweigend für alle meine Downstream-Abhängigkeiten bricht! Dies führt zu barocken APIs, die sich stark auf leicht verrottete Schlüsselwort-Argumente stützen, und die API von etwas, das sich im Laufe der Zeit entwickelt, ähnelt kaum dem, was Sie aus der Box heraus bauen würden, wenn Sie es noch einmal machen müssten. Folglich haben selbst die reinen Sicherheitsbedenken langfristige Auswirkungen auf das API-Design, sobald Sie möchten, dass die Leute auf Ihrer Arbeit aufbauen, anstatt sie einfach zu ersetzen, wenn es zu unhandlich wird.

    
___ tag123haskell ___ Haskell ist eine funktionale Programmiersprache mit starker statischer Typisierung, verzögerungsfreier Auswertung, umfangreicher Parallelitäts- und Parallelitätsunterstützung und einzigartigen Abstraktionsfunktionen. ___ tag123types ___ Typen und Typsysteme werden verwendet, um Abstraktionsstufen in Programmen zu erzwingen. ___ tag123typesystems ___ Typ-Systeme auferlegen Beschränkungen, welche Programme geschrieben werden dürfen, indem sie eine syntaktische Methode für den Betrieb mit diesen Beschränkungen bereitstellen. ___ tag123funktionale Programmierung ___ Funktionale Programmierung ist ein Programmierparadigma, das auf der Erzeugung von Abstraktionen unter Verwendung von Funktionen basiert, die Nebeneffekte und Zustandsänderungen vermeidet. Reine funktionale Programmierung ist threadsicher. ___ answer36147541 ___

Sie brauchen "Sicherheit", wenn Sie bereits wissen, was und wie Sie schreiben möchten. Es ist ein sehr kleiner Teil dessen, für welche Arten nützlich sind. Das Wichtigste an Typen ist, dass sie Ihr Denken strukturieren. Wenn jemand in Python %code% schreibt, sieht er %code% und %code% nicht als abstrakte Variablen - er sieht sie als Zahlen. Typen gibt es bereits in der internen Sprache des Menschen, Python hat einfach kein Typsystem, um darüber zu sprechen. Die eigentliche Frage in dem Streit um "typisierte gegen untypisierte (uneinheitliche) Programmierung" lautet: "Wollen wir unsere internen strukturierten Konzepte auf sichere und explizite oder unsichere und implizite Weise widerspiegeln?". Typen führen keine neuen Konzepte ein - es ist eine untypische Argumentation, die die bestehenden vergisst.

Wenn jemand auf einen Baum schaut (ich meine einen wirklich grünen), sieht er nicht jedes einzelne Blatt darauf, aber er behandelt es auch nicht als abstraktes, namenloses Objekt. "Ein Baum" - ist eine Annäherung, die für die meisten Fälle gut genug ist, und deshalb haben wir Systeme vom Typ Hindley-Milner, aber manchmal möchten Sie über einen bestimmten Baum sprechen und Sie möchten sich die Blätter ansehen. Und das gibt dir abhängige Typen: die Fähigkeit zu zoomen. "Ein Baum ohne Blätter", "ein Baum im Wald", "ein Baum in einer bestimmten Form" ... Abhängige Programmierungen sind nur ein weiterer Schritt in Richtung des menschlichen Denkens.

In einer weniger abstrakten Notiz habe ich einen Typ-Checker für eine Spielzeug-abhängige Typ-Sprache, wo alle Typisierungsregeln als Konstruktoren eines Datentyp . Sie müssen nicht in die Typprüfung eintauchen, um die Regeln des Systems zu verstehen. Das ist die Kraft des "Zoomens": Sie können so komplexe Invarianten einführen, wie Sie wollen, und so wesentliche Teile von nicht wichtigen unterscheiden.

Ein weiteres Beispiel für die leistungsabhängigen Typen gibt Ihnen verschiedene Formen der Reflexion. Schaue z.B. in der Pierre-Évariste Dagand Thesis , was beweist, dass

  

generische Programmierung ist nur Programmierung

Und natürlich sind Typen Andeutungen, viele Funktionen und Abstraktionen, die ich definiert habe, würde ich viel ungeschickter in einer schwach typisierten Sprache definieren, aber Typen haben bessere Alternativen vorgeschlagen.

Es gibt einfach keine Frage "Was soll ich wählen: einfache Typen oder abhängige Typen?". Abhängige Typen sind immer besser und sie umfassen natürlich einfache Typen. Die Frage ist "Was zu wählen: keine Typen oder abhängigen Typen?", Aber diese Frage steht nicht für mich.

    
___ qstntxt ___

In der Haskell-Community fügen wir langsam Funktionen abhängiger Typen hinzu. Abhängige Typen ist eine erweiterte Tippfunktion, mit der Arten von Werten abhängen können. Einige Sprachen wie Agda und Idris haben sie bereits. Es scheint ein sehr fortgeschrittenes Feature zu sein, das ein erweitertes Typsystem erfordert, bis Sie feststellen, dass Python abhängige Typen hatte die dynamische Typisierung abhängiger Typen, die tatsächlich abhängige Typen sein können oder nicht, von Anfang an.

Für fast jedes Programm in einer funktionalen Programmiersprache gibt es eine Möglichkeit, es als untypisierten Lambda-Kalkül-Begriff zu wiederholen, egal wie fortgeschritten die Typisierung ist. Das liegt daran, dass durch das Eintippen nur Programme eliminiert, neue nicht aktiviert werden.

Strong Typing gewinnt uns Sicherheit. Wie Klassen von Fehlern, die zur Laufzeit stattfanden, zur Laufzeit nicht mehr auftreten können. Diese Sicherheit ist ziemlich nett. Abgesehen von dieser Sicherheit, was gibt dir starkes Tippen?

Gibt es neben der Sicherheit noch weitere Vorteile eines starken Systemtyps?

(Beachten Sie, dass ich nicht sage, dass starkes Tippen wertlos ist. Sicherheit ist ein großer Nutzen für sich. Ich frage mich nur, ob es weitere Vorteile gibt.)

    
___ answer36143176 ___
  

Das liegt daran, dass durch das Eintippen nur Programme eliminiert, neue nicht aktiviert werden.

Dies ist keine korrekte Aussage. Typklassen ermöglichen es, Teile Ihres Programms aus Informationen auf Typenebene zu generieren.

Betrachte zwei Ausdrücke:

  1. %code%
  2. %code%

Hier verwende ich die Funktion %code% aus dem Modul %code% . Auf Termebene sind diese Ausdrücke identisch, nur ihre Typanmerkungen sind unterschiedlich. Die Ergebnisse, die sie zur Laufzeit erzeugen, unterscheiden sich jedoch ( %code% im ersten Fall, %code% im zweiten Fall).

Dies liegt daran, dass der Compiler Code aus den statischen Informationen generiert, die Sie haben. Um genauer zu sein, wählt es eine geeignete Klasseninstanz aus und übergibt ihr Wörterbuch an die polymorphe Funktion ( %code% in unserem Fall).

Dieses Beispiel ist einfach, aber es gibt wesentlich komplexere Anwendungsfälle. Mit der Bibliothek %code% können Sie Berechnungen schreiben, die in verschiedenen Berechnungskontexten ausgeführt werden (aka %code% s). Der Compiler fügt automatisch eine Menge Code ein, der die Berechnungskontexte verwaltet. In einer dynamisch typisierten Sprache hätten Sie keine statischen Informationen, um dies zu ermöglichen.

Wie Sie sehen, schneidet die statische Typisierung nicht nur falsche Programme ab, sondern schreibt auch richtige für Sie.

    
___ tag123dependentype ___ Abhängige Typen sind Typen, die von Werten abhängen. Sehr wenige Sprachen unterstützen sie - Beispiele sind Agda, ATS, Coq, Epigram, Scala (durch pfadabhängige Typen, eine enge Variante) und Idris, die darauf abzielt, nativen Code auf Systemebene zu produzieren. ___
1
Antwort

Abhängig eingegebene Warteschlange in Haskell

Ich habe versucht, meine eigene Frage zu Beispielen zu beantworten, die die Erweiterung PolyKinds in GHC verwenden und kam auf ein konkreteres Problem. Ich versuche, eine Warteschlange zu modellieren, die aus zwei Listen aufgebaut ist: der Kop...
29.12.2011, 10:13
1
Antwort

Ist es möglich, 'min' in eine normalisierende Theorie wie System-F oder den Kalkül von Konstruktionen einzugeben?

Diese min -Definition arbeitet an zwei Kirchennummern und gibt am wenigsten groß aus. Jede Zahl wird zu einer Fortsetzung, die ihr pred zum anderen schickt, zig und zag, bis Null erreicht ist. Darüber hinaus hängt eine der Zahlen jedes Mal, w...
18.11.2015, 19:26
1
Antwort

Was ist der Unterschied zwischen pfadabhängigen Typen und abhängigen Typen?

Scala hat pfadabhängige Typen, aber es wird gesagt, dass Scala keine abhängige Typisierung unterstützt. Was ist der Unterschied zwischen pfadabhängigen Typen und abhängigen Typen? Soweit ich verstehe, sind pfadabhängige Typen eine Art abhängi...
25.07.2014, 16:55
1
Antwort

Wie oder ist das möglich, zu beweisen oder zu verfälschen 'für alle (P Q: Prop), (P - Q) - (Q - P) - P = Q.' in Coq?

Ich möchte forall (P Q : Prop), (P -> Q) -> (Q -> P) -> P = Q. in Coq beweisen oder verfälschen. Hier ist mein Ansatz. %Vor% Aber inversion H tut nichts. Ich denke, es liegt vielleicht daran, dass die Unabhängigkeit des Coq...
26.10.2014, 10:39
1
Antwort

'Refl' Ding in der Kalkül der Konstruktionen?

In Sprachen wie Agda , Idris oder Haskell mit Typerweiterungen gibt es eine = -Typ-Sortierung ähnlich der folgenden %Vor% a :~: b bedeutet, dass a und b gleich sind. Kann ein solcher Typ im Konstruktionskalkül oder...
23.03.2016, 15:04
1
Antwort

Heterogene gesponserte Typen zurück zu Werten reflektieren, kompositorisch

Ich habe kürzlich mit -XDataKinds gespielt und würde gerne eine erweiterte Struktur mit Typfamilien erstellen und auf die Wertebene zurückziehen. Ich glaube, dass dies möglich ist, weil die kompositorischen Komponenten sehr einfach sind und d...
19.01.2015, 17:15
2
Antworten

Wie schreibe ich einen Funktionskörper in Idris, so dass der Typ der Funktionssignatur entspricht und das Ganze kompiliert wird

Ich möchte dafür folgendes kompilieren: %Vor% Dies kann nicht kompiliert werden, da der Compiler n nicht mit n + m vereinheitlichen kann. Ich verstehe, dass dies wegen der Signatur von take für Vect ist, aber ich kann nicht herausfi...
24.07.2014, 17:14
1
Antwort

Kann eine KnownNat zur Laufzeit zugewiesen werden?

Ich habe (erfolglos) versucht, ein "Objekt" * in Haskell in Runtime zu erstellen, dessen Typ zur Laufzeit mit abhängigen Typen definiert wurde. Ich habe dieses Tutorial zu abhängigen Typen und was sie gemacht haben verwenden, um einen Wert...
01.10.2017, 01:39
1
Antwort

Gibt es eine Verbindung zwischen 'a: ~: b' und '(a: == b): ~: True'?

Gibt es eine Verbindung zwischen propositional und < a href="https://hackage.haskell.org/package/singletons-2.2/docs/Data-Singletons-Prelude-Eq.html"> Gleichstellung gefördert? Sagen wir, ich habe %Vor% im Bereich für einige Symbol s...
20.06.2016, 13:09
2
Antworten

So emulieren Sie einen abhängigen Typ in Scala

Ich versuche einen generischen Restklassenring in Scala zu definieren. Ein Restklassenring wird durch irgendeinen Basisring (z. B. die ganzen Zahlen) und einen Modul (z. B. zwei) definiert, der ein Wert aus dem Basisring ist. Beide Ringe und ihr...
14.10.2010, 10:20