Was ist der WHNF eines neuen Typs und wie arbeitet rseq an einem neuen Typ?

8

Da newtype s beim Kompilieren effektiv entfernt werden, haben sie keine Thunks, nur Werte. Was passiert also, wenn ich nach seinem WHNF frage, indem ich % co_de verwende % ? Zum Beispiel in

%Vor%

wo rseq ist definiert als

%Vor%

wird Sum ausgewertet oder nicht? Ist es irgendwo spezifiziert / dokumentiert, damit ich mich darauf verlassen kann?

Update: Lassen Sie mich meine Zweifel genauer erklären. Intuitiv sagt man: " lengthyComputation ist streng, so klar ist sein WHNF das WHNF dessen, was drin ist". Aber ich denke, das ist eine sehr ungenaue Abkürzung und die Argumentation ist nicht so klar. Lassen Sie mich ein Beispiel geben:

Für standardmäßige newtype -Typen kann WHNF als ein Formular definiert werden, in dem wir wissen, welcher Konstruktor zum Erstellen des Werts verwendet wurde. Wenn wir zum Beispiel data nicht hätten, könnten wir unser eigenes

erstellen %Vor%

und ähnlich für jeden seq -Typ, nur durch Mustervergleich für einen seiner Konstruktoren.

Nun nehmen wir

%Vor%

und erstellen Sie eine ähnliche Funktion data :

%Vor%

klar, hier ist nichts zu WHNF gezwungen. (Immerhin wissen wir immer, welcher Konstruktor verwendet wurde.) Nach der Kompilierung ist seqIdentity identisch mit seqIdentity . Tatsächlich ist es nicht möglich, polymorph const id so zu erstellen, dass die Auswertung eines Wertes, der in seqIdentity ! Wir könnten WHNF a von Identity einfach als unmodifizierten Wert definieren und es wäre konsistent. Ich glaube also, die Frage ist, wie ist WHNF für newtype s definiert? Oder gibt es keine strenge Definition, und das Verhalten "es ist die WHNF von dem, was drin ist" wird einfach als etwas Offensichtliches angenommen?

    
Petr Pudlák 02.12.2012, 12:40
quelle

1 Antwort

8

Im Abschnitt Umbenennungen von Datentypen im Bericht

>
  

Im Gegensatz zu algebraischen Datentypen ist der newtype-Konstruktor N nicht verschoben, so dass N ⊥ dasselbe wie ⊥ ist.

Hier

%Vor%

so ist die schwache Kopf-Normalform eines neuen Typs die WHNF des umschlossenen Typs und

%Vor%

wertet lengthyComputation aus (wenn der gesamte Ausdruck ausgewertet wird, eine bloße Bindung

%Vor%

natürlich nicht, aber das ist das gleiche ohne den Konstruktor newtype.

Die definierenden Gleichungen für seq sind

%Vor%

und daher

%Vor%

und in

%Vor%

Die seq wird benötigt, um herauszufinden, ob lengthyComputation :: Int ist oder nicht. Dazu muss lengthyComputation :: Int ausgewertet werden.

Re Aktualisierung:

newtype s sind unlifted , dh der Konstruktor ist kein Wertkonstruktor semantisch (nur syntaktisch). Der Mustervergleich für einen newtype -Konstruktor ist im Gegensatz zum Mustervergleich für einen data -Konstruktor nicht streng. Gegeben

%Vor%

ein "Mustervergleich"

%Vor%

entspricht vollständig

%Vor%

Die Übereinstimmung ist immer erfolgreich und wertet nichts aus. Der Konstruktor erzwingt nur den Typ und "Mustererkennung" deaktiviert den Typ des Wertes.

seq ist magisch, es kann nicht in Haskell implementiert werden. Sie können eine Funktion schreiben, die dasselbe tut wie seq für einen data type, wie Ihre seqMaybe oben, in Haskell, aber nicht für eine (polymorphe) newtype , weil "pattern matching" für den newtype Konstruktor ist nicht streng. Sie müssten die Konstruktoren des umschlossenen Typs anpassen, aber für eine polymorphe newtype haben Sie sie nicht.

    
Daniel Fischer 02.12.2012, 13:00
quelle