Krytyka monady IO jest postrzegana jako monada państwowa działająca na świecie

46

IOMonada w Haskell jest często tłumaczyć jako monady stan, w którym państwo jest świat. Zatem wartość typu IO amonada jest postrzegana jako coś w rodzaju worldState -> (a, worldState).

Jakiś czas temu przeczytałem artykuł (lub wpis na blogu / liście mailowej), który skrytykował ten pogląd i podał kilka powodów, dla których jest on nieprawidłowy. Ale nie pamiętam ani artykułu, ani powodów. Ktoś wie

Edycja: Artykuł wydaje się zagubiony, zacznijmy więc gromadzić tutaj różne argumenty. Zaczynam nagrodę, aby uczynić rzeczy bardziej interesującymi.

Edycja: Artykuł, którego szukałem, dotyczy walki z niezręczną drużyną: monadyczne wejście / wyjście, współbieżność, wyjątki i rozmowy w języku obcym w Haskell przez Simona Peytona Jonesa. (Dzięki odpowiedzi TacTics.)

Petr Pudlák
źródło
1
Czy to ten artykuł (lub starsza wersja )?
Joachim Sauer,
@JoachimSauer Dzięki, to także ciekawy artykuł, ale nie tego szukam. Ten koncentrował się na paradygmacie stanu świata.
Petr Pudlák,
Z góry mojej głowy, komentarze tutaj są dobrym początkiem
Adam
1
Co w tym kontekście oznacza „świat”? Zakładam, że nie oznacza to „Ziemi”. Czy to jakiś globalny zasięg? Autor, który to napisał, sprzedaje się krótko. Jeśli chce jednocześnie zmylić i zmiażdżyć ego swoich czytelników, powinien nazwać to „Stanem Wszechświata” lub „Bogiem”. Świat. Pa! Wy, młodzi ludzie, nie aspirujecie obecnie wystarczająco wysoko!
GlenPeterson

Odpowiedzi:

33

Problem IO a = worldState -> (a, worldState)polega na tym, że gdyby to była prawda, moglibyśmy to udowodnić forever (putStrLn "Hello") :: IO ai undefined :: IO abyć równi. Oto dowód dzięki uprzejmości 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))

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

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

W związku z tym forever m = fix (\r -> \w -> r (snd $ m w)) = ⊥

W szczególności, forever (putStrLn "Hello") = ⊥a zatem forever (putStrLn "Hello")i undefinedsą równoważne programy. Oczywiście nie należy ich uważać za równoważne programy, zarówno w teorii, jak iw praktyce.

Zauważ, że ten model jest zły nawet bez wywoływania współbieżności.

Russell O'Connor
źródło
7
Czy ktoś jest zaskoczony, że nieterminowy program jest równoważny undefinedczystej semantyce Haskella? Różne setyki Haskella powinny być nierozróżnialne! Ale kiedy myślimy operacyjnie o naszych programach, chcemy rozróżnić także różne rodzaje ⊥, nawet jeśli IOnie jest to zaangażowane; Obchodzi mnie to, czy mój program zgłasza wyjątek czy wchodzi w nieskończoną pętlę, nawet jeśli możesz udowodnić, że są one równe, udowadniając, że oba są ⊥. To jednak nie jest sprzeczność.
Ben
3
Oznaczenia ⊥ i [0,1 ..] są różne, mimo że oba są „nie kończące”. Różnica polega na tym, że ⊥ oznacza niekończące się i nieproduktywne obliczenia, podczas gdy [0,1 ..] jest nieterminalne, ale produktywne. Oczekujemy, że (na zawsze (putStrLn „Hello”)) będzie mieć podobne nieterminacyjne, ale produktywne oznaczenie.
Russell O'Connor,
1
Ale na pewno forever (putStrLn "Hello")nie jest tak [0,1..]. Twój dowód nie jest konkretny worldState, dlatego dotyczy on również zwykłej monady państwowej. Więc forever (someModificationWith "Hello")jest również denotacyjnie równoważny z ⊥. Jestem całkowicie zaskoczony tym wynikiem; nie jest produktywny w semantyce denotacyjnej, a to, co komputer robi operacyjnie, gdy czekamy wiecznie, jest nieistotne. To samo dotyczy forever (putStrLn "Hello"); nie tworzy i nie powinien tworzyć nowego stanu świata, który możemy w jakiś sposób leniwie konsumować.
Ben
Czy języki programowania, takie jak Mercury i Clean, które używają jawnego przekazywania stanu świata w celu zapewnienia deklaratywnego modelu IO, są zasadniczo błędne?
Ben
@Ben, czy masz na myśli, w jaki sposób przekazywanie świata działa z współbieżnością? Czy widziałeś kod rozetowy dla współbieżności Merkurego? Zastanawiałem się, co to znaczy semantycznie.
CMCDragonkai
12

Oto banalna odpowiedź: każda zmiana stanu monady stanu jest spowodowana działaniami podejmowanymi w monadzie. Jeśli rzeczywiście wyjaśnienie „WorldState -> (a, WorldState)” zawiera tę samą właściwość, a WorldState jest czystą wartością, którą zmieniają tylko monada IO, to jest źle. Zmiany czasu, zawartość plików, stan uchwytów itp. Mogą się zmieniać niezależnie od tego, co dzieje się w monadzie IO. O to chodzi w monadzie IO. Fakt, że GHC przekazuje poniżej wartość RealWorld (lub w / e to było) pod spodem, gwarantuje, że wszystko działa w porządku, o ile mi wiadomo, jeśli to (może to być coś, co można umieścić w wartości ST).

Christopher Done
źródło
8
to właściwie nie jest problem. można modelować operację wiązania jako modyfikację stanu świata pochodzącą z pewnego stałego, ale nieznanego magazynu reguł.
sclv
1
@sclv: Tak, ale to naprawić, ale niepoznawalny-sklep zasada jest czynnikiem różnicującym sprawia, że IO nie monady stan, ta niespójność nie występuje w monady państwowej
Jimmy Hoffa
Argument, który słyszałem przeciwko stanowi WorldState, dotyczy współbieżności, chociaż nie pamiętam dokładnego argumentu. Ale i tak hipotezuję, że WorldState może również w tym zakodować przyszłość, więc nadal nie widzę problemu. Oczywiście, chyba coś mi umknęło.
Thomas Eding
@JimmyHoffa: Możesz jednak nosić stan magazynu reguł.
sclv
1
@ JimmyHoffa: to jest cel abstrakcji. Ponadto, w odpowiedzi na mój pierwszy komentarz, Oczyść modele IO jako światowe przejście jawnie i szczęśliwie, wykorzystując typy unikatowości, aby upewnić się, że nie oszukujesz i nie powielasz świata. Jest to jeden ze sposobów wymuszenia abstrakcji.
sclv
12

Napisałem wpis na blogu na temat modelowania IO jako formy asymetrycznej coroutine komunikującej się z systemem wykonawczym dla twojego języka. (Jest to wprawdzie trzecia część serii)

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

Ten post wyjaśnia, dlaczego trudno jest rozumieć semantykę „przemijania świata”.

Edward KMETT
źródło
+1 - szczególnie interesujące, ponieważ od dawna planowałem wdrożenie IO języka, który projektuję w podobny sposób! :)
Jules
8

Zobacz: Walka z niezręczną drużyną .

Głównym powodem jest to, że modele stanów RealWorld monady IO nie działają dobrze z współbieżnością. SPJ w tym czytelnym klasycznym faworyzuje semantykę operacyjną, aby ją zrozumieć.

Taktyka
źródło
Myślę, że to był oryginalny artykuł, którego szukałem, głównie sekcja 3.1. Jeśli opublikowałeś go przed redagowaniem pytania, zaakceptowałbym twoją odpowiedź, ale teraz myślę, że bardziej sprawiedliwie będzie poczekać do końca, aby zobaczyć wszystkie pomysły opublikowane przez innych.
Petr Pudlák
5

Główna skarga na modele stanów RealWorld polega na tym, że, jak mówi TacTics, przekazywanie świata niekoniecznie działa z współbieżnością. Ale Wouter Swierstra i Thorsten Altenkirch pokazali, jak rozumować współbieżność jako efekt „przemijania świata”, z ustaloną, ale arbitralną sekwencją przeplatających się wątków w swoim artykule „Beauty in the Beast: A Functional Sematics for the Awkward Squad”: http : //www.staff.science.uu.nl/~swier004/Publications/BeautyInTheBeast.pdf

Odpowiadający temu kod znajduje się w Hackage jako IOSpec: http://hackage.haskell.org/package/IOSpec

Myślę, że teza Woutera jest bardziej szczegółowa: http://www.staff.science.uu.nl/~swier004/Publications/Thesis.pdf

sclv
źródło