Sama seperti judulnya: jaminan apa yang ada untuk unit pengembalian fungsi Haskell yang akan dievaluasi? Orang akan berpikir bahwa tidak perlu menjalankan evaluasi apa pun dalam kasus seperti itu, kompilator dapat mengganti semua panggilan seperti itu dengan ()
nilai langsung kecuali jika ada permintaan eksplisit untuk ketatnya, dalam hal ini kode mungkin harus memutuskan apakah harus kembali ()
atau bawah.
Saya telah bereksperimen dengan ini di GHCi, dan sepertinya kebalikannya terjadi, yaitu fungsi seperti itu tampaknya dievaluasi. Contoh yang sangat primitif adalah
f :: a -> ()
f _ = undefined
Mengevaluasi f 1
kesalahan melempar karena kehadiran undefined
, jadi beberapa evaluasi pasti terjadi. Tidak jelas seberapa dalam evaluasi berjalan; kadang-kadang tampaknya masuk sedalam yang diperlukan untuk mengevaluasi semua panggilan ke fungsi yang kembali ()
. Contoh:
g :: [a] -> ()
g [] = ()
g (_:xs) = g xs
Kode ini berulang tanpa batas jika disajikan dengan g (let x = 1:x in x)
. Tapi kemudian
f :: a -> ()
f _ = undefined
h :: a -> ()
h _ = ()
dapat digunakan untuk menunjukkan bahwa h (f 1)
pengembalian ()
, jadi dalam hal ini tidak semua subekspresi bernilai unit dievaluasi. Apa aturan umum di sini?
ETA: tentu saja saya tahu tentang kemalasan. Saya bertanya apa yang mencegah penulis kompiler membuat kasus khusus ini lebih malas dari biasanya.
ETA2: ringkasan dari contoh-contoh: GHC tampaknya memperlakukan ()
persis seperti jenis lainnya, yaitu seolah-olah ada pertanyaan tentang nilai reguler yang menghuni jenis tersebut harus dikembalikan dari suatu fungsi. Fakta bahwa hanya ada satu nilai yang tampaknya tidak (ab) digunakan oleh algoritma optimasi.
ETA3: ketika saya mengatakan Haskell, maksud saya Haskell-sebagaimana-didefinisikan-oleh-the-Report, bukan Haskell-the-H-in-GHC. Tampaknya ada asumsi yang tidak dibagikan seluas yang saya bayangkan (yang 'oleh 100% pembaca'), atau saya mungkin bisa merumuskan pertanyaan yang lebih jelas. Meski begitu, saya menyesal mengubah judul pertanyaan, karena awalnya bertanya jaminan apa yang ada untuk fungsi yang dipanggil.
ETA4: sepertinya pertanyaan ini sudah berjalan, dan saya menganggapnya belum terjawab. (Saya sedang mencari fungsi 'pertanyaan dekat' tetapi hanya menemukan 'jawab pertanyaan Anda sendiri' dan karena tidak bisa dijawab, saya tidak turun jalan itu.) Tidak ada yang membawa apa pun dari Laporan yang akan memutuskan dengan cara apa pun , yang saya tergoda untuk menafsirkan sebagai jawaban yang kuat tetapi tidak pasti 'tidak ada jaminan untuk bahasa seperti itu'. Yang kami tahu adalah bahwa implementasi GHC saat ini tidak akan melewatkan evaluasi fungsi tersebut.
Saya mengalami masalah saat porting aplikasi OCaml ke Haskell. Aplikasi asli memiliki struktur saling rekursif dari banyak jenis, dan kode menyatakan sejumlah fungsi yang disebut assert_structureN_is_correct
N dalam 1..6 atau 7, masing-masing mengembalikan unit jika struktur memang benar dan melemparkan pengecualian jika tidak . Selain itu, fungsi-fungsi ini saling memanggil karena mereka menguraikan kondisi kebenaran. Di Haskell ini lebih baik ditangani menggunakan Either String
monad, jadi saya menyalinnya seperti itu, tetapi pertanyaan sebagai masalah teoritis tetap ada. Terima kasih atas semua masukan dan balasan.
f 1
"diganti" oleh undefined
dalam semua kasus.
... -> ()
dapat 1) mengakhiri dan mengembalikan ()
, 2) mengakhiri dengan pengecualian / kesalahan runtime dan gagal mengembalikan apa pun, atau 3) menyimpang (rekursi tak terbatas). GHC tidak mengoptimalkan kode dengan asumsi hanya 1) dapat terjadi: jika f 1
diminta, ia tidak melewati evaluasi dan kembali ()
. Semantik Haskell adalah untuk mengevaluasi dan melihat apa yang terjadi di antara 1,2,3.
()
(baik tipe atau nilainya) dalam pertanyaan ini. Semua pengamatan yang sama terjadi jika Anda mengganti () :: ()
dengan, katakanlah, di 0 :: Int
mana-mana. Ini semua hanya konsekuensi lama yang membosankan dari evaluasi malas.
()
tipe, ()
dan undefined
.
h1::()->() ; h1 () = ()
danh2::()->() ; h2 _ = ()
. Jalankan keduanyah1 (f 1)
danh2 (f 1)
, dan perhatikan bahwa hanya yang pertama yang dituntut(f 1)
.