Kritik daran, dass die IO-Monade als eine auf der Welt operierende staatliche Monade angesehen wird

46

Die IOMonade in Haskell wird oft als Staatsmonade bezeichnet, in der der Staat die Welt ist. Ein Wert vom Typ IO amonad wird also als so etwas wie angesehen worldState -> (a, worldState).

Vor einiger Zeit habe ich einen Artikel (oder einen Blog- / Mailinglisten-Beitrag) gelesen, in dem diese Ansicht kritisiert und verschiedene Gründe genannt wurden, warum sie nicht korrekt ist. Aber ich kann mich weder an den Artikel noch an die Gründe erinnern. Weiß jemand Bescheid?

Bearbeiten: Der Artikel scheint verloren zu sein, also wollen wir hier verschiedene Argumente zusammenfassen. Ich starte eine Prämie, um die Dinge interessanter zu machen.

Bearbeiten: Der Artikel, den ich gesucht habe, befasst sich mit der schwierigen Situation: monadische Ein- / Ausgabe, Parallelität, Ausnahmen und fremdsprachige Anrufe in Haskell von Simon Peyton Jones. (Dank der Antwort von TacTics.)

Petr Pudlák
quelle
1
Ist es dieser Artikel (oder diese ältere Version davon )?
Joachim Sauer
@JoachimSauer Danke, es ist auch ein interessanter Artikel, aber nicht der, den ich suche. Dieser konzentrierte sich auf das Paradigma des Weltzustands.
Petr Pudlák
Die Kommentare hier sind ein guter Anfang
Adam
1
Was bedeutet "Welt" in diesem Zusammenhang? Ich nehme an, es bedeutet nicht "Die Erde". Ist es eine Art globaler Bereich? Der Autor, der das geschrieben hat, verkauft sich knapp. Wenn er das Ego seiner Leser gleichzeitig verwirren und zerschlagen will, sollte er es "Der Staat ist das Universum" oder "Der Gottesstaat" nennen. Welt. Pah! Ihr jungen Leute strebt heutzutage nicht hoch genug!
GlenPeterson

Antworten:

33

Das Problem dabei IO a = worldState -> (a, worldState)ist, dass wenn dies wahr wäre, wir das beweisen könnten forever (putStrLn "Hello") :: IO aund undefined :: IO agleich sind. Hier ist der Beweis mit freundlicher Genehmigung von 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))

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

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

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

Insbesondere forever (putStrLn "Hello") = ⊥und daher forever (putStrLn "Hello")und undefinedsind gleichwertige Programme. Es ist jedoch klar, dass sie weder in der Theorie noch in der Praxis als gleichwertige Programme gelten.

Beachten Sie, dass dieses Modell falsch ist, auch wenn keine Parallelität aufgerufen wird.

Russell O'Connor
quelle
7
Ist jemand überrascht, dass ein nicht abschließendes Programm undefinedder reinen Semantik von Haskell entspricht? In Haskells reiner Semantik sollen verschiedene nicht zu unterscheiden sein! Aber wenn wir operativ über unsere Programme nachdenken, wollen wir auch dann verschiedene Arten von ⊥ unterscheiden, wenn dies IOnicht involviert ist. Es ist mir egal, ob mein Programm eine Ausnahme auslöst oder in eine Endlosschleife eintritt, auch wenn Sie beweisen können, dass diese gleich sind, indem Sie beweisen, dass beide ⊥ sind. Das ist aber eigentlich kein Widerspruch.
Ben
3
Die Bezeichnungen von ⊥ und [0,1 ..] sind unterschiedlich, obwohl beide "nicht terminierend" sind. Der Unterschied besteht darin, dass ⊥ nicht terminierende und nicht produktive Berechnungen bedeutet, während [0,1 ..] nicht terminierend, aber produktiv ist. Wir erwarten (für immer (putStrLn "Hello")) eine ähnliche nicht terminierende, aber produktive Bezeichnung.
Russell O'Connor
1
Ist forever (putStrLn "Hello")aber [0,1..]sicher nicht so . Ihr Beweis ist nicht spezifisch worldState, deshalb gilt er auch für die reguläre Staatsmonade. forever (someModificationWith "Hello")Ist also auch gleichbedeutend mit ⊥. Ich bin völlig überrascht von diesem Ergebnis; Es ist in der Denotationssemantik nicht produktiv, und was der Computer im Betrieb tut , während wir ewig warten, ist irrelevant. Gleiches für forever (putStrLn "Hello"); Es kann und sollte keinen neuen Weltstaat hervorbringen, den wir irgendwie träge konsumieren können.
Ben
Sind Programmiersprachen wie Mercury und Clean, die explizite Weltzustandsübergabe verwenden, um ein deklaratives Modell für E / A bereitzustellen, grundsätzlich falsch?
Ben
@Ben beziehen Sie sich darauf, wie das Vorbeigehen in der Welt mit Parallelität funktioniert? Haben Sie den Rosettencode für Mercurys Nebenläufigkeit gesehen? Ich habe mich gefragt, was das auch semantisch bedeutet.
CMCDragonkai
12

Hier ist eine triviale Antwort: Jede Änderung des Status der Staatsmonade ist auf Aktionen zurückzuführen, die in der Monade ausgeführt wurden. Wenn in der Tat die Erklärung "WorldState -> (a, WorldState)" dieselbe Eigenschaft beansprucht, wobei WorldState ein reiner Wert ist, den nur die E / A-Monade ändert, ist dies falsch. Zeitänderungen, der Inhalt von Dateien, der Status von Handles usw. können sich unabhängig davon ändern, was in der E / A-Monade geschieht. Das ist der Punkt der IO-Monade. Die Tatsache, dass GHC einen RealWorld-Wert umgibt (oder es war), soll garantieren, dass die Dinge, soweit ich weiß, in Ordnung sind (kann nur etwas sein, das in den ST-Wert eingefügt werden kann).

Christopher Fertig
quelle
8
das ist eigentlich kein problem Sie können den Bindevorgang als eine Änderung des Weltzustands modellieren, die von einem festen, aber nicht erkennbaren Regelspeicher abgeleitet wurde.
sclv
1
@sclv: Ja, aber dieser feste, aber nicht erkennbare Regelspeicher ist der Unterscheidungsfaktor, der die E / A nicht zur staatlichen Monade macht. Diese Inkonsistenz wird in der staatlichen Monade
Jimmy Hoffa,
Ein Argument, das ich gegen den WorldState-Status gehört habe, hängt mit der Parallelität zusammen, obwohl ich mich nicht an das genaue Argument erinnern kann. Trotzdem gehe ich davon aus, dass WorldState auch die Zukunft darin verschlüsseln könnte, sodass ich das Problem immer noch nicht wirklich sehe. Natürlich vermisse ich etwas.
Thomas Eding
@JimmyHoffa: Sie können den Regelspeicher jedoch im Status herumtragen.
sclv
1
@ JimmyHoffa: Dies ist der Zweck der Abstraktion. Um meinem ersten Kommentar nachzugehen, solltest du die Modelle I und O explizit und glücklich als weltumspannend betrachten und Eindeutigkeitstypen verwenden, um sicherzustellen, dass du die Welt nicht betrügst und "duplizierst". Dies ist eine Möglichkeit, die Abstraktion durchzusetzen.
sclv
12

Ich schrieb einen Blogbeitrag zum Thema, wie IO als eine Form der asymmetrischen Coroutine modelliert werden kann, die mit dem Laufzeitsystem für Ihre Sprache kommuniziert. (Es ist zugegebenermaßen der dritte Teil einer Serie)

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

In diesem Beitrag geht es darum, warum es unangenehm ist, über die Semantik des "Weltvergehens" nachzudenken.

Edward KMETT
quelle
+1 - besonders interessant, da ich schon lange geplant habe, das IO der Sprache, die ich entwerfe, auf ähnliche Weise zu implementieren! :)
Jules
8

Siehe Bekämpfung der ungeschickten Truppe .

Der Hauptgrund dafür ist, dass RealWorld-Statusmodelle der E / A-Monade nicht gut mit Parallelität funktionieren. SPJ in diesem lesbaren Klassiker bevorzugt die Verwendung einer operativen Semantik, um dies zu verstehen.

Taktik
quelle
Ich glaube, das ist der Originalartikel, den ich gesucht habe, hauptsächlich Abschnitt 3.1. Wenn Sie es gepostet hätten, bevor ich die Frage bearbeitet habe, hätte ich Ihre Antwort akzeptiert, aber jetzt denke ich, dass es fairer ist, bis zum Ende zu warten, um alle Ideen zu sehen, die andere posten.
Petr Pudlák
5

Die Hauptbeschwerde bei den RealWorld-Zustandsmodellen ist, dass, wie TacTics sagt, die Weitergabe der Welt nicht unbedingt mit der Parallelität zusammenarbeitet. Aber Wouter Swierstra und Thorsten Altenkirch gezeigt , wie man Grund , sich über die Parallelität als „Welt-Passing“ -Effekt, mit einem Fest aber willkürlicher Reihenfolge Fäden der Verschachtelung in ihrem Papier „Schönheit im Biest: eine funktionelle Sematics für die ungeschickte Squad“: http : //www.staff.science.uu.nl/~swier004/Publications/BeautyInTheBeast.pdf

Der entsprechende Code befindet sich auf Hackage als IOSpec: http://hackage.haskell.org/package/IOSpec

Ich denke, Wouters These geht detaillierter: http://www.staff.science.uu.nl/~swier004/Publications/Thesis.pdf

sclv
quelle