Da newtype
s während der Kompilierung effektiv entfernt werden, haben sie keine Thunks, nur Werte. Was passiert also, wenn ich nach WHNF mit rseq
frage? Zum Beispiel inWas ist der WHNF eines neuen Typs und wie arbeitet RSEQ an einem neuen Typ?
Sum (lengthyComputation :: Int) `using` rseq
wo Sum
ist definiert als
newtype Sum a = Sum { getSum :: a }
wird lengthyComputation
ausgewertet oder nicht erhalten? Ist es irgendwo angegeben/dokumentiert, damit ich mich darauf verlassen kann?
Update: Lassen Sie mich meine Zweifel näher erläutern. Intuitiv sagt man: "newtype
ist streng so klar, dass sein WHNF das WHNF dessen ist, was innen eingewickelt wird". 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 Standard data
Typen kann WHNF als eine Form definiert werden, wo wir wissen, welcher Konstruktor für die Konstruktion des Werts verwendet wurde. Wenn zum Beispiel haben wir nicht seq
haben, konnten wir unsere eigenen
seqMaybe :: Maybe a -> b -> b
seqMaybe Nothing = id
seqMaybe _ = id
erstellen und in ähnlicher Weise für jede data
Art, nur durch Muster auf einer seiner Konstrukteure entsprechen.
Jetzt ist
newtype Identity a = Identity { runIdentity :: a }
und erstellen eine ähnliche seqIdentity
Funktion übernehmen lassen:
seqIdentity :: Identity a -> b -> b
seqIdentity (Identity _) = id
klar, nichts gezwungen hier WHNF. (Immerhin wissen wir immer, welcher Konstruktor verwendet wurde.) Nach der Kompilierung ist seqIdentity
identisch mit . In der Tat ist es nicht möglich, polymorph seqIdentity
so zu erstellen, dass es die Auswertung eines Werts innerhalb Identity
eingezwängt würde! Wir könnten WHNF a von newtype
einfach als den Wert unmodifiziert definieren und es wäre konsistent. Also ich glaube, 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?
Vielen Dank für Ihre Antwort. Aber ich denke, dass der Schritt "newtype" streng ist, so dass sein WHNF das WHNF dessen ist, was drin ist "ist nicht präzise. Ich änderte die Frage und versuchte, meine Zweifel ausführlich auszudrücken. –
Es ist nicht so, dass "newtype's streng sind, es ist, dass sie _unlifted_ sind, die die WHNF propagieren lassen. –
Erweiterte Antwort, klärt das mehr? –