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:
data Foo = Foo Int Int !Int !(Maybe Int)
f = Foo (2+2) (3+3) (4+4) (Just (5+5))
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:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
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 und 8
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 nicht Just
, und das speichern, aber wir gehen nicht weiter. Das bedeutet, dass wir nicht speichern, Just 10
sondern tatsächlich Just (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 x !y = x*y
f (1+1) (2+2)
wird den Thunk zurückgeben (1+1)*4
.