Ist es nicht auch möglich, so ziemlich jede nicht-reine Funktion wie eine Funktion der realen Welt zu beschreiben? Können wir uns z.B. malloc in C als eine Funktion vorstellen, die eine RealWorld und eine Int annimmt und einen Zeiger und eine RealWorld zurückgibt, nur dass in der IO-Monade die RealWorld implizit ist?
Mit Sicherheit ...
Die ganze Idee der funktionalen Programmierung besteht darin, Programme als eine Kombination von kleine, unabhängige Berechnungen größere Berechnungen anzustellen.
Mit diesen unabhängig Berechnungen haben Sie viele Vorteile, die von prägnanten Programmen über effizienten und effizient parallelisierbaren Code, Faulheit bis hin zu der strengen Garantie reichen, dass die Kontrolle wie beabsichtigt fließt - ohne die Möglichkeit von Störungen oder der Verfälschung beliebiger Daten.
Jetzt - in einigen Fällen (wie IO) brauchen wir unreinen Code. Berechnungen mit solchen Operationen kann nicht unabhängig sein - sie könnten beliebige Daten einer anderen Berechnung verändern.
Der Punkt ist - Haskell ist immer rein , IO
ändert daran nichts.
Unsere unreinen, nicht-unabhängigen Codes müssen also eine gemeinsame Abhängigkeit erhalten - wir müssen eine RealWorld
. Für jede zustandsabhängige Berechnung, die wir durchführen wollen, müssen wir also diese RealWorld
auf die wir unsere Änderungen anwenden - und jede andere zustandsabhängige Berechnung, die Änderungen sehen oder vornehmen möchte, muss die RealWorld
auch.
Dies geschieht entweder explizit oder implizit durch die IO
Monade ist irrelevant. Man baut ein Haskell-Programm als eine riesige Berechnung auf, die Daten transformiert, und ein Teil dieser Daten ist die RealWorld
.
Sobald die erste main :: IO ()
aufgerufen wird, wenn Ihr Programm mit der aktuellen realen Welt als Parameter ausgeführt wird, wird diese reale Welt durch alle involvierten unsauberen Berechnungen getragen, genau wie Daten in einer State
. Das ist es, was monadische >>=
(binden) kümmert sich darum.
Und wo die RealWorld
nicht bekommt (wie bei reinen Berechnungen oder ohne jegliche >>=
-ing zu main
), gibt es keine Möglichkeit, etwas damit anzufangen. Und wo es する bekommen, das geschah durch rein funktionale Übergabe eines (impliziten) Parameters. Deshalb ist
let foo = putStrLn "AAARGH" in 42
absolut nichts bewirkt - und warum die IO
Monade ist - wie alles andere auch - rein. Was innerhalb dieses Codes geschieht, kann natürlich unrein sein, aber es ist alles darin gefangen und hat keine Chance, mit nicht verbundenen Berechnungen zu interferieren.
4 Stimmen
Sie können meine Antwort hier nachlesen: stackoverflow.com/questions/3117583