Kritik terhadap monad IO dipandang sebagai monad negara yang beroperasi di dunia

46

The IOmonad di Haskell sering dijelaskan sebagai monad negara di mana negara adalah dunia. Jadi nilai tipe IO amonad dipandang sebagai sesuatu seperti worldState -> (a, worldState).

Beberapa waktu yang lalu saya membaca artikel (atau posting blog / milis) yang mengkritik pandangan ini dan memberikan beberapa alasan mengapa itu tidak benar. Tetapi saya tidak dapat mengingat baik artikel maupun alasannya. Adakah yang tahu?

Sunting: Artikel ini sepertinya hilang, jadi mari kita mulai mengumpulkan berbagai argumen di sini. Saya memulai hadiah untuk membuat hal-hal lebih menarik.

Sunting: Artikel yang saya cari adalah Menangani skuad canggung: input / output monadik, konkurensi, pengecualian, dan panggilan bahasa asing di Haskell oleh Simon Peyton Jones. (Terima kasih atas jawaban TacTics.)

Petr Pudlák
sumber
1
Apakah ini artikel (atau versi yang lebih lama )?
Joachim Sauer
@ JoachimSauer Terima kasih, ini juga artikel yang menarik, tapi bukan yang saya cari. Yang itu difokuskan pada paradigma negara-dunia.
Petr Pudlák
Dari atas kepala saya, komentar di sini adalah awal yang baik
Adam
1
Apa arti "dunia" dalam konteks ini? Saya kira itu tidak berarti "Bumi." Apakah ini semacam ruang lingkup global? Penulis yang menulis ini menjual dirinya pendek. Jika dia ingin secara bersamaan membingungkan dan menghancurkan ego para pembacanya, dia harus menyebutnya "Negara adalah Semesta" atau "Negara Dewa." Dunia. Pah! Kalian anak muda tidak bercita-cita cukup tinggi akhir-akhir ini!
GlenPeterson

Jawaban:

33

Masalahnya IO a = worldState -> (a, worldState)adalah jika ini benar maka kita bisa membuktikannya forever (putStrLn "Hello") :: IO adan undefined :: IO asama. Berikut adalah bukti milik dolio (2010, irc):

forever m
 =
m >> forever m
 =
fix (\r -> m >> r)
 = {definition of >> for worldState -> (a, worldState)}
fix (\r -> \w -> r (snd $ m w))

Kata pengantar singkat: (\r w -> r (snd $ m w)) ⊥ = ⊥

(\r w -> r (snd $ m w)) ⊥
  =
\w -> ⊥ (snd $ m w))
  =
⊥ . snd . m
  =
⊥

Karena itu forever m = fix (\r -> \w -> r (snd $ m w)) = ⊥

Secara khusus forever (putStrLn "Hello") = ⊥dan karenanya forever (putStrLn "Hello")dan undefinedadalah program yang setara. Namun, jelas mereka tidak seharusnya dianggap sebagai program yang setara, secara teori atau dalam praktik.

Perhatikan bahwa model ini salah bahkan tanpa meminta konkurensi.

Russell O'Connor
sumber
7
Adakah yang terkejut bahwa program nonterminating setara dengan undefinedsemantik murni Haskell? Berbagai supposeds seharusnya tidak dapat dibedakan dalam semantik murni Haskell! Tetapi ketika kita memikirkan secara operasional tentang program-program kita, kita juga ingin membedakan berbagai jenis ⊥, bahkan ketika IOtidak terlibat; Saya peduli apakah program saya melempar pengecualian atau memasuki infinite loop, bahkan jika Anda dapat membuktikan bahwa keduanya sama dengan membuktikan bahwa keduanya ⊥. Itu sebenarnya bukan kontradiksi.
Ben
3
Denotasi ⊥ dan [0,1 ..] berbeda meskipun keduanya "non-terminating". Perbedaannya adalah bahwa ⊥ menunjukkan perhitungan non-terminasi dan non-produktif, sedangkan [0,1 ..] non-terminasi tetapi produktif. Kami berharap (selamanya (putStrLn "Halo")) memiliki denotasi yang tidak berhenti tetapi produktif.
Russell O'Connor
1
Tapi forever (putStrLn "Hello")tentu saja tidak seperti [0,1..]. Bukti Anda tidak khusus untuk worldState, oleh karena itu juga berlaku untuk keadaan umum monad. Jadi forever (someModificationWith "Hello")juga secara denotasional setara dengan ⊥. Saya sama sekali tidak terkejut dengan hasil itu; itu tidak produktif dalam semantik denotasional, dan apa yang dilakukan komputer secara operasional sementara kita menunggu selamanya tidak relevan. Hal yang sama untuk forever (putStrLn "Hello"); itu tidak dan tidak seharusnya menghasilkan negara dunia baru yang entah bagaimana bisa kita konsumsi dengan malas.
Ben
Apakah bahasa pemrograman seperti Mercury dan Clean yang menggunakan passing status-negara eksplisit untuk memberikan model deklaratif untuk IO secara fundamental salah?
Ben
@ Apakah Anda mengacu pada bagaimana cara kerja passing dunia dengan concurrency? Pernahkah Anda melihat kode rosetta untuk konkurensi Mercury? Saya bertanya-tanya apa artinya juga secara semantik.
CMCDragonkai
12

Inilah jawaban yang sepele: perubahan apa pun pada negara bagian monad adalah karena tindakan apa pun yang dijalankan dalam monad. Jika memang penjelasan "WorldState -> (a, WorldState)" mengklaim properti yang sama, dengan WorldState menjadi nilai murni yang hanya diubah oleh IO monad, itu salah. Perubahan waktu, konten file, status pegangan, dll. Dapat berubah secara independen dari apa yang terjadi di monad IO. Itulah inti dari mono IO. Fakta bahwa GHC melewati sekitar nilai RealWorld (atau w / e itu) di bawahnya adalah untuk memastikan semuanya berjalan sesuai urutan, sejauh yang saya tahu, jika itu (mungkin hanya sesuatu yang dimasukkan ke dalam nilai ST).

Christopher Done
sumber
8
itu sebenarnya bukan masalah. Anda dapat memodelkan operasi bind sebagai melakukan modifikasi pada negara dunia yang berasal dari beberapa toko aturan yang tidak diketahui.
sclv
1
@sclv: ya, tetapi toko aturan yang tetap-tetapi-tidak diketahui ini adalah faktor pembeda yang membuat IO bukan monad negara, ketidakkonsistenan ini tidak ditemukan di monad negara
Jimmy Hoffa
Argumen yang saya dengar tentang status WorldState terkait dengan konkurensi, meskipun saya tidak dapat mengingat argumen yang tepat. Tetapi meskipun demikian, saya berhipotesis bahwa WorldState juga dapat menyandikan masa depan ke dalamnya, jadi saya masih tidak benar-benar melihat masalahnya. Tentu saja, saya kira saya kehilangan sesuatu.
Thomas Eding
@JimmyHoffa: Anda bisa membawa-bawa toko aturan di negara bagian.
sclv
1
@JimmyHoffa: ini adalah tujuan abstraksi. Juga, untuk menindaklanjuti komentar awal saya, model Clean IO sebagai pelintas dunia secara eksplisit dan bahagia, menggunakan tipe keunikan untuk memastikan bahwa Anda tidak menipu dan "menduplikasi" dunia. Ini adalah salah satu cara menegakkan abstraksi.
sclv
12

Saya menulis posting blog dengan topik bagaimana memodelkan IO sebagai bentuk coroutine asimetris yang berkomunikasi dengan sistem runtime untuk bahasa Anda. (Ini diakui sebagai bagian ketiga dari seri)

http://comonad.com/reader/2011/free-monads-for-less-3/

Tulisan itu mencakup sedikit mengapa canggung untuk beralasan tentang semantik 'pelintas dunia'.

Edward KMETT
sumber
+1 - terutama menarik, karena saya telah lama berencana mengimplementasikan IO bahasa yang saya desain dengan cara yang mirip dengan ini! :)
Jules
8

Lihat Menangani Pasukan Canggung .

Alasan utama adalah model negara RealWorld dari monad IO tidak bekerja dengan baik dengan konkurensi. SPJ dalam bantuan klasik yang dapat dibaca ini menggunakan semantik operasional untuk memahaminya.

Taktik
sumber
Saya percaya ini adalah artikel asli yang saya cari, terutama bagian 3.1. Jika Anda telah mempostingnya sebelum saya mengedit pertanyaan, saya akan menerima jawaban Anda, tetapi sekarang saya pikir akan lebih adil untuk menunggu sampai akhir, untuk melihat semua ide yang orang lain akan posting.
Petr Pudlák
5

Keluhan utama tentang model negara RealWorld adalah bahwa, seperti yang dikatakan TacTics, pelintasan dunia tidak selalu bekerja dengan konkurensi. Tetapi Wouter Swierstra dan Thorsten Altenkirch menunjukkan bagaimana alasan tentang konkurensi sebagai efek "kelewat dunia", dengan urutan yang tetap namun sewenang-wenang dari benang-benang interleaving dalam makalah mereka "Beauty in the Beast: Sebuah Fungsional Fungsional untuk Pasukan Awkward": http : //www.staff.science.uu.nl/~swier004/Publications/BeautyInTheBeast.pdf

Kode yang sesuai dengan ini ada di Hackage as IOSpec: http://hackage.haskell.org/package/IOSpec

Saya pikir tesis Wouter lebih rinci: http://www.staff.science.uu.nl/~swier004/Publications/Thesis.pdf

sclv
sumber