Noch ein neuer Typ vs. Daten (stilistisches Problem)

8

Ich kenne die Unterschiede zwischen data , newtype und type sehr gut. Ich schreibe ein kleines Skript, das eine Art Syntaxbaum erstellt. Fast alle Typen haben einen Konstruktor . Ich vermeide type , um die Sicherheit zu erzwingen (mehrere "verschiedene" Typen könnten am Ende den gleichen Typ in Haskell haben). Ich interessiere mich nicht für Faulheit / Strenge in diesem Fall, noch interessiere ich mich für Leistung (dieser Teil ist keineswegs leistungskritisch). Ich konzentriere mich hauptsächlich auf Stil. Ich habe drei Möglichkeiten:

  1. Verwenden Sie nur data . Das fühlt sich gut an, außer dass ich viele Typen mit nur einem Konstruktor mit einem Argument habe. Der Code sieht etwas verschwenderisch aus ... Obwohl mir der Leistungsgewinn egal ist, fühlt es sich einfach nicht richtig an.
  2. Verwenden Sie nur newtype . Dies führt zu einer großen Hässlichkeit mit Tupeln bei mehreren Parametern.
  3. Mix data und newtype , die etwas uneinheitlich und leicht nervig aussehen. Ich möchte alle Typen auf eine einzige konsistente Weise deklariert haben.

Ich bin in einem Dilemma zwischen 1 und 3 zu wählen.

    
aelguindy 15.02.2012, 12:58
quelle

2 Antworten

11

In diesem Fall würde ich data universell aus verschiedenen Gründen verwenden. Erstens, aus Gründen der Übereinstimmung mit den Fällen mit mehreren Argumenten (die definitiv sein sollten data , nicht newtype ).

Zweitens, und am wichtigsten, newtype hat verschiedene Semantiken bis data ! Der Konstruktor einer newtype ist streng, im Gegensatz zu denen von data , die nicht strikt sind, es sei denn, Sie verwenden strikte Felder explizit. Selbst wenn dir die Strenge egal ist oder alle Felder deiner data s streng sind, gibt es immer noch einige subtile Elemente Unterschiede .

Ich glaube nicht, dass one-constructor, one-argent data types verschwenderisch sind - syntaktisch sind sie genauso leicht wie ein newtype und scheinen semantisch wichtiger für mich zu sein.

Sie haben gesagt, dass Sie sich nicht um die Leistung sorgen, aber wenn der Runtime-Box-Overhead von data wirklich war, dann könnten Sie sie mischen, solange Sie sich dessen bewusst sind semantische Unterschiede. Wenn Sie jedoch -funbox-strict-fields verwenden, kann GHC das Einzelkonstrukt, ein Argument data s für Sie optimieren, wenn sie als strikte Felder in anderen Datentypen auftreten.

Im Allgemeinen sollten Sie newtype verwenden, wenn Sie einen vorhandenen Typ umbrechen, um die Sicherheit / Abstraktion während der Kompilierung zu gewährleisten, oder um eigene Instanzen zu definieren, und data immer dann verwenden, wenn der Typ gerade passiert besteht aus einem einzelnen Feld und ist kein Wrapper.

    
ehird 15.02.2012, 13:02
quelle
6

Wenn ich echte Programme erstelle, die keine subtilen Dinge mit Faulheit machen, verwende ich fast immer newtype für Datentypen mit einem einzelnen Konstruktor und Argument und data für alles andere:

%Vor%

Zumindest, wenn Sie sich selbst finden schreiben

%Vor%

Die Semantik ist identisch zu

%Vor%

Sie können also auch die data Version verwenden, weil sie hübscher ist. Tatsächlich

%Vor%

unterscheiden sich in der Semantik, aber in keiner Weise, die für "echte" Programme wichtig ist, wo wir nicht erwarten, den Unterschied zwischen _|_ und Foo _|_ kennen zu müssen (weil alle Werte voll sind) -definiert sowieso).

Es gibt noch eine andere Sache, auf die man achten sollte: Einheitlichkeit bei den Erklärungen ist etwas, worauf man achten sollte . Es gibt an, dass es eine Abstraktionsebene gibt, die Sie in Ihrem Programm nicht codieren, die Sie implizit verlassen. Sehen Sie, ob Sie diese Ebene codieren können, bis keine parallele Deklarationsstruktur mehr verfügbar ist. Dies ist nicht immer möglich, aber versuchen Sie sich zu nähern.

    
luqui 15.02.2012 17:30
quelle

Tags und Links