Saya menemukan definisi berikut ketika saya mencoba mempelajari Haskell menggunakan proyek nyata untuk mengendarainya. Saya tidak mengerti apa arti tanda seru di depan setiap argumen dan sepertinya buku-buku saya tidak menyebutkannya.
data MidiMessage = MidiMessage !Int !MidiMessage
haskell
syntax
lazy-evaluation
David
sumber
sumber
Jawaban:
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:
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:
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, dan8
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
atauJust
sesuatu, dan menyimpannya, tetapi kita tidak melangkah lebih jauh. Itu berarti bahwa kita tidak menyimpanJust 10
tetapi sebenarnyaJust (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 (1+1) (2+2)
akan mengembalikan thunk(1+1)*4
.sumber
seq
.Cara sederhana untuk melihat perbedaan antara argumen konstruktor yang ketat dan tidak ketat adalah bagaimana mereka berperilaku ketika mereka tidak terdefinisi. Diberikan
Karena argumen non-ketat tidak dievaluasi oleh
second
, menyampaikanundefined
tidak menyebabkan masalah:Tetapi argumen yang ketat tidak bisa
undefined
, bahkan jika kita tidak menggunakan nilainya:sumber
!
simbol, daripada menggali detail implementasi internal.Saya percaya ini adalah penjelasan ketat.
Haskell adalah bahasa fungsional murni dan malas , tetapi kadang-kadang overhead dari kemalasan bisa terlalu banyak atau boros. Jadi untuk mengatasinya, Anda dapat meminta kompiler untuk mengevaluasi argumen sepenuhnya ke fungsi alih-alih menguraikan pemicu.
Ada informasi lebih lanjut di halaman ini: Kinerja / Ketat .
sumber
map Just [1,2,3]
untuk mendapatkan [Hanya 1, Hanya 2, Hanya 3]) dan seterusnya. Saya merasa terbantu untuk memikirkan kemampuan untuk menyesuaikan pola dengan mereka serta fasilitas yang sama sekali tidak terkait.