Ich bin auf die folgende Definition gestoßen, als ich versuchte, Haskell mit einem echten Projekt zu lernen, um es voranzutreiben. Ich verstehe nicht, was das Ausrufezeichen vor jedem Argument bedeutet, und meine Bücher schienen es nicht zu erwähnen.
data MidiMessage = MidiMessage !Int !MidiMessage
haskell
syntax
lazy-evaluation
David
quelle
quelle
Antworten:
Es ist eine Strengeerklärung. Grundsätzlich bedeutet dies, dass es bei der Erstellung des Datenstrukturwerts als "schwache Kopfnormalform" ausgewertet werden muss. Schauen wir uns ein Beispiel an, damit wir sehen können, was dies bedeutet:
Die
f
obige Funktion gibt bei Auswertung einen "Thunk" zurück, dh den Code, der ausgeführt werden muss, um seinen Wert herauszufinden. Zu diesem Zeitpunkt existiert noch nicht einmal ein Foo, nur der Code.Aber irgendwann könnte jemand versuchen, hinein zu schauen, wahrscheinlich durch eine Musterübereinstimmung:
Dies wird genug Code ausführen, um das zu tun, was es braucht, und nicht mehr. Es wird also ein Foo mit vier Parametern erstellt (da Sie nicht hineinschauen können, ohne dass es vorhanden ist). Das erste, da wir es testen, müssen wir es bis dahin bewerten
4
, wo wir feststellen, dass es nicht übereinstimmt.Der zweite muss nicht ausgewertet werden, da wir ihn nicht testen. Anstatt
6
an diesem Speicherort gespeichert zu werden, speichern wir den Code nur für eine mögliche spätere Auswertung(3+3)
. Das wird nur dann zu einer 6, wenn jemand darauf schaut.Der dritte Parameter hat jedoch ein
!
vor sich, wird also streng ausgewertet:(4+4)
wird ausgeführt und8
an diesem Speicherort gespeichert.Der vierte Parameter wird ebenfalls streng ausgewertet. Aber hier wird es etwas schwierig: Wir bewerten nicht vollständig, sondern nur die schwache normale Kopfform. Dies bedeutet, dass wir herausfinden, ob es etwas ist
Nothing
oder nichtJust
, und das speichern, aber wir gehen nicht weiter. Das bedeutet, dass wir nicht speichern,Just 10
sondern tatsächlichJust (5+5)
, und den Thunk im Inneren unbewertet lassen. Dies ist wichtig zu wissen, obwohl ich denke, dass alle Implikationen davon eher über den Rahmen dieser Frage hinausgehen.Sie können Funktionsargumente auf dieselbe Weise mit Anmerkungen versehen, wenn Sie die
BangPatterns
Spracherweiterung aktivieren :f (1+1) (2+2)
wird den Thunk zurückgeben(1+1)*4
.quelle
seq
.Eine einfache Möglichkeit, den Unterschied zwischen strengen und nicht strengen Konstruktorargumenten zu erkennen, besteht darin, wie sie sich verhalten, wenn sie nicht definiert sind. Gegeben
Da das nicht strenge Argument von nicht bewertet wird
second
, verursacht die Übergabeundefined
kein Problem:Aber das strenge Argument kann nicht sein
undefined
, auch wenn wir den Wert nicht verwenden:quelle
!
Symbols erklärt, anstatt sich mit internen Implementierungsdetails zu befassen.Ich glaube, es ist eine Strenge Annotation.
Haskell ist eine reine und faule funktionale Sprache, aber manchmal kann der Aufwand an Faulheit zu viel oder verschwenderisch sein. Um dies zu bewältigen, können Sie den Compiler bitten, die Argumente für eine Funktion vollständig auszuwerten, anstatt Thunks zu analysieren.
Weitere Informationen finden Sie auf dieser Seite: Leistung / Strenge .
quelle
map Just [1,2,3]
um [Nur 1, Nur 2, Nur 3] zu erhalten) und so weiter. Ich finde es hilfreich, über die Fähigkeit nachzudenken, Muster mit ihnen abzugleichen, sowie über eine völlig unabhängige Einrichtung.