Lemma: Dengan asumsi kesetaraan eta kita memilikinya (\x -> ⊥) = ⊥ :: A -> B
.
Bukti: ⊥ = (\x -> ⊥ x)
dengan kesetaraan eta, dan (\x -> ⊥ x) = (\x -> ⊥)
dengan pengurangan di bawah lambda.
Laporan Haskell 2010, bagian 6.2 menentukan seq
fungsi dengan dua persamaan:
seq :: a -> b -> b seq ⊥ b = ⊥ seq ab = b, jika a ≠ ⊥
Itu kemudian mengklaim "Sebagai konsekuensinya, ⊥ tidak sama dengan \ x -> ⊥, karena seq dapat digunakan untuk membedakannya."
Pertanyaan saya adalah, apakah itu benar-benar konsekuensi dari definisi seq
?
Argumen implisit tampaknya yang seq
tidak dapat diperhitungkan jika seq (\x -> ⊥) b = ⊥
. Namun saya belum dapat membuktikan bahwa hal seperti seq
itu tidak dapat dihitung. Bagi saya, sepertinya seq
itu monoton, dan terus-menerus, yang menempatkannya dalam ranah komputabel.
Algoritme yang mengimplementasikan seperti seq mungkin bekerja dengan mencoba mencari beberapa x
tempat f x ≠ ⊥
dengan menyebutkan domain f
dimulai dengan ⊥. Meskipun implementasi seperti itu, bahkan jika mungkin sama sekali, menjadi sangat berbulu ketika kita ingin membuat seq
polimorfik.
Apakah ada bukti bahwa tidak ada dihitung seq
bahwa mengidentifikasi (\x -> ⊥)
dengan ⊥ :: A -> B
? Atau, apakah ada beberapa konstruksi seq
yang tidak sesuai (\x -> ⊥)
dengan ⊥ :: A -> B
?
sumber
seq
seq
Perhatikan bahwa spesifikasi
seq
yang Anda kutip bukan definisi. Mengutip laporan Haskell "Fungsi seq didefinisikan oleh persamaan : [dan kemudian persamaan yang Anda berikan]".Perilaku seperti itu akan melanggar spesifikasi
seq
.Yang penting, karena
seq
bersifat polimorfik,seq
tidak dapat didefinisikan dalam hal dekonstruksi (proyeksi / pencocokan pola, dll.) Pada salah satu dari dua parameter.Jika
seq' (\x -> ⊥) b
, orang mungkin berpikir kita bisa menerapkan parameter pertama (yang merupakan fungsi) ke beberapa nilai dan kemudian. Keluar. Tetapi,seq
tidak pernah dapat mengidentifikasi parameter pertama dengan nilai fungsi (bahkan jika itu menjadi satu untuk beberapa penggunaanseq
) karena jenis polimorfik parametriknya. Parametrisitas berarti kita tidak tahu apa pun tentang parameter. Selain itu,seq
tidak pernah bisa mengambil ekspresi dan memutuskan "apakah ini ⊥?" (lih. Masalah Berhenti),seq
hanya dapat mencoba untuk mengevaluasinya, dan itu sendiri berbeda dengan ⊥.Yang
seq
dilakukan adalah mengevaluasi parameter pertama (tidak sepenuhnya, tetapi untuk "bentuk normal kepala lemah" [1], yaitu ke konstruktor paling atas), lalu mengembalikan parameter kedua. Jika parameter pertama kebetulan⊥
(yaitu, perhitungan non terminating) maka mengevaluasi itu menyebabkanseq
non-terminate, dan dengan demikianseq ⊥ a = ⊥
.[1] Teorema Gratis di Hadirat seq - Johann, Voigtlander http://www.iai.uni-bonn.de/~jv/p76-voigtlaender.pdf
sumber
f : forall a . a -> T
(di manaT
ada beberapa tipe lain), makaf
tidak dapat menerapkan dekonstruktor apa pun pada argumen pertamanya karena tidak tahu dekonstruktor mana yang akan diterapkan. Kami tidak dapat melakukan "kasus" pada jenis. Saya telah mencoba untuk meningkatkan jawaban di atas (termasuk mengutip informasi tentangseq
mengevaluasi bentuk kepala normal).Samson Abramsky mempertimbangkan masalah ini sejak lama dan menulis sebuah makalah berjudul " The Lazy Lambda Calculus ". Jadi, jika Anda menginginkan definisi formal, di sinilah Anda akan melihat.
sumber
Membuktikan bahwa λ x. Ω ≠ Ω in adalah salah satu tujuan yang Abramsky tetapkan untuk teori kalkulus lambda malasnya (halaman 2 makalahnya , sudah dikutip oleh Uday Reddy), karena keduanya dalam bentuk kepala normal yang lemah. Pada definisi 2.7, ia membahas secara eksplisit bahwa eta-reduksi λ x. M x → M umumnya tidak valid, tetapi dimungkinkan jika M berakhir di setiap lingkungan. Ini tidak berarti bahwa M harus menjadi fungsi total - hanya bahwa mengevaluasi M harus diakhiri (dengan mengurangi menjadi lambda, misalnya).
Pertanyaan Anda tampaknya dimotivasi oleh masalah praktis (kinerja). Namun, meskipun Laporan Haskell mungkin kurang dari sepenuhnya jelas, saya ragu bahwa menyamakan λ x. ⊥ dengan ⊥ akan menghasilkan implementasi Haskell yang berguna; apakah itu mengimplementasikan Haskell '98 atau tidak masih bisa diperdebatkan, tetapi memberikan komentar, jelas bahwa penulis bermaksud untuk menjadi demikian.
Akhirnya, bagaimana seq menghasilkan elemen untuk tipe input yang sewenang-wenang? (Saya tahu QuickCheck mendefinisikan typeclass sewenang-wenang untuk itu, tetapi Anda tidak diizinkan untuk menambahkan kendala seperti itu di sini) Ini melanggar parametrik.
Diperbarui : Saya tidak berhasil mengkodekan hak ini (karena saya tidak begitu lancar di Haskel), dan memperbaiki ini sepertinya memerlukan
runST
wilayah bersarang . Saya mencoba menggunakan sel referensi tunggal (dalam monad ST) untuk menyimpan elemen arbitrer seperti itu, membacanya nanti, dan membuatnya tersedia secara universal. Parametrisitas membuktikan bahwa dibreak_parametricity
bawah ini tidak dapat didefinisikan (kecuali dengan kembali ke bawah, misalnya kesalahan), sementara itu bisa memulihkan elemen yang seq diusulkan akan menghasilkan.Saya harus mengakui bahwa saya agak kabur memformalkan bukti parametrik yang diperlukan di sini, tetapi penggunaan parametrikitas informal ini merupakan standar di Haskell; tetapi saya belajar dari tulisan Derek Dreyer bahwa teori yang dibutuhkan dengan cepat dikerjakan dalam tahun-tahun terakhir ini.
EDIT:
sumber
(\x -> writeSTRef cell (Just x) >> return x)
input acak tidak menjalankan penulisan ke sel. Hanya perintah ST yang membuatnya menjadi urutan yang dilewatirunST
yang pernah dieksekusi. Demikian pula, menjalankanmain = (putStrLn "Hello") `seq` (return ())
tidak mencetak apa pun ke layar.