È una dichiarazione di rigore. Fondamentalmente, significa che deve essere valutato in quello che viene chiamato "modulo normale testa debole" quando viene creato il valore della struttura dei dati. Diamo un'occhiata a un esempio, in modo che possiamo vedere esattamente cosa significa:
data Foo = Foo Int Int !Int !(Maybe Int)
f = Foo (2+2) (3+3) (4+4) (Just (5+5))
La funzione f
sopra, quando valutata, restituirà un "thunk": cioè il codice da eseguire per capirne il valore. A quel punto, un Foo non esiste ancora, solo il codice.
Ma a un certo punto qualcuno potrebbe provare a guardarci dentro, probabilmente attraverso una combinazione di schemi:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
Questo eseguirà abbastanza codice per fare ciò di cui ha bisogno, e non di più. Quindi creerà un Foo con quattro parametri (perché non puoi guardarci dentro senza che esistano). Il primo, dal momento che lo stiamo testando, dobbiamo valutare fino in fondo 4
, dove ci rendiamo conto che non corrisponde.
Il secondo non ha bisogno di essere valutato, perché non lo stiamo testando. Così, invece di 6
essere memorizzato in quella posizione di memoria, ci limiteremo a memorizzare il codice per un eventuale successiva valutazione, (3+3)
. Ciò si trasformerà in un 6 solo se qualcuno lo guarda.
Il terzo parametro, tuttavia, ha un !
davanti, quindi viene valutato rigorosamente: (4+4)
viene eseguito e 8
viene archiviato in quella posizione di memoria.
Anche il quarto parametro viene valutato rigorosamente. Ma qui è dove diventa un po 'complicato: stiamo valutando non completamente, ma solo a una forma della testa normale debole. Ciò significa che capiamo se è Nothing
o Just
qualcosa del genere e lo memorizziamo, ma non andiamo oltre. Ciò significa che non immagazziniamo Just 10
ma in realtà Just (5+5)
, lasciando il thunk all'interno non valutato. Questo è importante da sapere, anche se penso che tutte le implicazioni di ciò vadano piuttosto oltre lo scopo di questa domanda.
È possibile annotare gli argomenti della funzione allo stesso modo, se si abilita l' BangPatterns
estensione della lingua:
f x !y = x*y
f (1+1) (2+2)
restituirà il thunk (1+1)*4
.