Ini deklarasi ketat. Pada dasarnya, itu berarti bahwa itu harus dievaluasi untuk apa yang disebut "bentuk normal kepala lemah" ketika nilai struktur data dibuat. Mari kita lihat sebuah contoh, sehingga kita dapat melihat apa artinya ini:
data Foo = Foo Int Int !Int !(Maybe Int)
f = Foo (2+2) (3+3) (4+4) (Just (5+5))
Fungsi di f
atas, ketika dievaluasi, akan mengembalikan "thunk": yaitu kode yang akan dieksekusi untuk mencari nilainya. Pada titik itu, Foo bahkan belum ada, hanya kodenya.
Tetapi pada titik tertentu seseorang mungkin mencoba melihat ke dalamnya, mungkin melalui pencocokan pola:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
Ini akan mengeksekusi kode yang cukup untuk melakukan apa yang dibutuhkan, dan tidak lebih. Jadi itu akan membuat Foo dengan empat parameter (karena Anda tidak dapat melihat di dalamnya tanpa itu ada). Yang pertama, sejak kami mengujinya, kami perlu mengevaluasi sampai ke sana 4
, di mana kami menyadari itu tidak cocok.
Yang kedua tidak perlu dievaluasi, karena kami tidak mengujinya. Jadi, daripada 6
disimpan di lokasi memori itu, kami hanya akan menyimpan kode untuk kemungkinan evaluasi nanti (3+3)
,. Itu akan berubah menjadi 6 hanya jika seseorang melihatnya.
Namun, parameter ketiga ada !
di depannya, jadi dievaluasi secara ketat: (4+4)
dijalankan, dan 8
disimpan di lokasi memori itu.
Parameter keempat juga dievaluasi secara ketat. Tapi di sinilah agak rumit: kita mengevaluasi tidak sepenuhnya, tetapi hanya untuk bentuk kepala normal yang lemah. Ini berarti bahwa kita mencari tahu apakah itu sesuatu Nothing
atau Just
sesuatu, dan menyimpannya, tetapi kita tidak melangkah lebih jauh. Itu berarti bahwa kita tidak menyimpan Just 10
tetapi sebenarnya Just (5+5)
, membiarkan bagian dalam tidak dievaluasi. Ini penting untuk diketahui, meskipun saya pikir semua implikasi ini melampaui lingkup pertanyaan ini.
Anda dapat membuat anotasi argumen fungsi dengan cara yang sama, jika Anda mengaktifkan BangPatterns
ekstensi bahasa:
f x !y = x*y
f (1+1) (2+2)
akan mengembalikan thunk (1+1)*4
.