Warum hat Haskell keine Datensätze mit Strukturtypisierung?

7

Ich habe gehört, dass Haskell strukturelle Typisierung beschrieben hat. Aufzeichnungen sind eine Ausnahme, obwohl, wie ich es verstehe. Zum Beispiel kann foo nicht mit etwas vom Typ HRec2 aufgerufen werden, obwohl HRec und HRec2 in ihren Feldern nur nominell unterschiedlich sind.

%Vor%

Gibt es eine Erklärung für die Ablehnung der Erweiterung der strukturellen Typisierung auf alles einschließlich Datensätze?

Gibt es statisch typisierte Sprachen mit Strukturtypisierung auch für Datensätze? Gibt es vielleicht eine Debatte darüber, über die ich im Allgemeinen für alle statisch getippten Sprachen lesen kann?

    
user782220 12.01.2014, 05:22
quelle

4 Antworten

8

Haskell hat strukturierte Typen, aber keine strukturelle Typisierung, und das wird sich wahrscheinlich nicht ändern. *

Die Ablehnung, nominell verschiedene, aber strukturell ähnliche Typen als austauschbare Argumente zuzulassen, wird als Typsicherheit bezeichnet. Es ist eine gute Sache. Haskell hat sogar eine Newtype-Deklaration, um Typen bereitzustellen, die nur nominell verschieden sind, um mehr Typsicherheit durchzusetzen. Type Safety ist eine einfache Möglichkeit, Bugs frühzeitig zu erkennen, anstatt sie zur Laufzeit zuzulassen.

Zusätzlich zu amindfvs guter Antwort, die Ad-hoc-Polymorphismus über typeclasses (effektiv eine von einem Programmierer deklarierte Merkmaläquivalenz) enthält, gibt es parametrischen Polymorphismus, bei dem Sie absolut jeden Typ zulassen, also [a] erlaubt jeden Typ in Ihrer Liste und BTree a erlaubt jeden Typ in Ihrem Binärbaum.

Dies gibt drei Antworten auf "sind diese Typen austauschbar?".

  1. Nein; Der Programmierer hat es nicht gesagt.
  2. Entspricht einem bestimmten Zweck, weil der Programmierer das gesagt hat.
  3. Es ist mir egal - ich kann dasselbe mit dieser Datensammlung machen, weil es keine Eigenschaft der Daten selbst verwendet.

Es gibt keinen 4: Compiler, der Programmierer außer Kraft setzt, weil sie zufällig ein paar Ints und einen String wie in dieser anderen Funktion benutzt haben.

* Ich sagte, Haskell wird sich wahrscheinlich nicht in strukturelle Typisierung verwandeln. Es gibt einige Diskussionen, um eine Form von erweiterbaren Datensätzen einzuführen, aber es ist nicht geplant, (Int,(Int,Int)) als gleich (Int, Int, Int) oder Triple {one::Int, two::Int, three::Int} als Triple2 {one2::Int, two2::Int, three2::Int} zu zählen.

    
enough rep to comment 12.01.2014, 10:05
quelle
9

Haskell-Aufzeichnungen sind nicht wirklich "weniger strukturell" als der Rest des Typsystems. Jeder Typ ist entweder vollständig spezifiziert oder "spezifisch vage" (d. H. Mit einer Typklasse definiert).

Um sowohl HRec als auch HRec2 bis f zuzulassen, haben Sie ein paar Optionen:

Algebraische Typen:

Hier definieren Sie HRec und HRec2 Datensätze, die beide Teil des Typs HRec sind:

%Vor%

(abwechselnd und vielleicht idiomatisch:)

%Vor%

Typklassen

Hier definieren Sie foo als fähig, jeden Typ als Eingabe zu akzeptieren, solange eine typeclass-Instanz für diesen Typ geschrieben wurde:

%Vor%

Die Verwendung von typeclasses erlaubt Ihnen, weiter zu gehen als die normale strukturelle Typisierung - Sie können Typen akzeptieren, in die die notwendigen Informationen eingebettet sind, auch wenn die Typen nicht ähnlich aussehen, z. B .:

%Vor%

Wir können fromInteger (oder irgendeine andere Funktion) ausführen, um die benötigten Daten von dem zu erhalten, was wir haben!

    
amindfv 12.01.2014 07:12
quelle
1

Um Ihre letzte Frage zu beantworten, haben Go und Scalas definitiv strukturelle Typisierung. Einige Leute (einschließlich mir) würden das "statisch unsichere Typisierung" nennen, da es implizit alle gleich benannten Methoden in einem Programm mit der gleichen Semantik deklariert, was "gruselige Aktion auf Distanz" bedeutet, die Code in Quelldatei bezieht Code in einer Bibliothek, die das Programm noch nie gesehen hat.

IMO, besser zu verlangen, dass die gleichnamigen Methoden explizit erklären, dass sie einem benannten semantischen "Modell" des Verhaltens entsprechen.

Ja, der Compiler würde garantieren, dass die Methode aufrufbar ist, aber es ist nicht viel sicherer als zu sagen:

%Vor%

Und der Compiler darf eine beliebige Implementierung wählen, die length sein kann oder nicht.

(Eine ähnliche Idee kann mit Scala "implicits" oder Haskell (GHC?) "Reflection" Paket gemacht werden.)

    
misterbee 13.01.2014 16:29
quelle
0

Ich kenne zwei Bibliotheksimplementierungen strukturierter Datensätze in Haskell:

HList ist älter und wird in einem ausgezeichneten Papier erklärt: Haskells übersehenes Objektsystem (kostenlos online, aber SO lässt mich nicht mehr Links hinzufügen)

Vinyl ist neuer und verwendet neue GHC-Funktionen. Es gibt mindestens eine Bibliothek, Vinyl-gl, die es benutzt.

Ich kann jedoch den Sprachentwurf Ihrer Frage nicht beantworten.

    
bergey 13.01.2014 15:01
quelle