Critique de la monade d'IO considérée comme une monade d'état opérant sur le monde

46

La IOmonade à Haskell est souvent décrite comme une monade d’État où l’État est le monde. Ainsi, une valeur de type IO amonad est considérée comme quelque chose comme worldState -> (a, worldState).

Il y a quelque temps, j'ai lu un article (ou un article de blog / liste de diffusion) qui critiquait ce point de vue et donnait plusieurs raisons pour expliquer que ce n'était pas correct. Mais je ne me souviens ni de l'article ni des raisons. Quelqu'un sait?

Edit: L'article semble perdu, commençons donc à rassembler divers arguments ici. Je commence une prime pour rendre les choses plus intéressantes.

Edit: L’article que je cherchais s’attaque au groupe délicat: entrées / sorties monadiques, accès simultanés, exceptions et appels en langue étrangère dans Haskell de Simon Peyton Jones. (Merci à la réponse de TacTics.)

Petr Pudlák
la source
1
Est-ce cet article (ou cette ancienne version de celui-ci )?
Joachim Sauer
@ JoachimSauer Merci, c'est aussi un article intéressant, mais ce n'est pas celui que je cherche. Celui-ci était axé sur le paradigme de l'état du monde.
Petr Pudlák
Du haut de ma tête, les commentaires ici sont un bon début
Adam
1
Que veut dire "monde" dans ce contexte? Je présume que cela ne signifie pas "la Terre". Est-ce une sorte de portée mondiale? L'auteur qui a écrit ceci se vend court. S'il veut simultanément confondre et écraser l'égo de ses lecteurs, il devrait l'appeler "L'Etat est l'univers" ou "L'Etat divin". Monde. Pah! Vous, les jeunes, n'aspirez pas assez haut ces jours-ci!
GlenPeterson

Réponses:

33

Le problème IO a = worldState -> (a, worldState)est que si cela était vrai, nous pourrions le prouver forever (putStrLn "Hello") :: IO aet nous undefined :: IO asommes égaux. Voici la preuve fournie par 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))

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

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

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

En particulier forever (putStrLn "Hello") = ⊥et par conséquent forever (putStrLn "Hello"), undefinedsont des programmes équivalents. Cependant, il est clair qu'ils ne sont pas censés être considérés comme des programmes équivalents, en théorie ou en pratique.

Notez que ce modèle est faux même sans invoquer la simultanéité.

Russell O'Connor
la source
7
Est-ce que quelqu'un est surpris qu'un programme sans fin soit équivalent à undefinedla sémantique pure de Haskell? Différents s sont supposés être indiscernables dans la sémantique pure de Haskell! Mais lorsque nous réfléchissons de manière opérationnelle à nos programmes, nous voulons également distinguer différents types de, même lorsque cela IOn’est pas impliqué; Je me soucie de savoir si mon programme génère une exception ou entre dans une boucle infinie, même si vous pouvez prouver que ces éléments sont égaux en prouvant qu'ils sont tous les deux. Ce n'est pas réellement une contradiction cependant.
Ben
3
Les dénotations de ⊥ et [0,1 ..] sont distinctes même si elles sont toutes deux "non terminantes". La différence est que ⊥ is désigne des calculs non-terminaux et non productifs, alors que [0,1 ..] est non-terminal mais productif. Nous nous attendons à ce que (forever (putStrLn "Hello")) ait une dénotation similaire, non-terminante mais productive.
Russell O'Connor
1
Mais ce forever (putStrLn "Hello")n'est pas comme [0,1..], sûrement. Votre preuve n'est pas particulière à worldState, donc elle s'applique également à la monade d'état régulière. Donc forever (someModificationWith "Hello")est aussi dénotationnellement équivalent à ⊥. Je ne suis absolument pas surpris par ce résultat. cela n'est pas productif dans la sémantique dénotationnelle, et ce que l'ordinateur fait de manière opérationnelle pendant que nous attendons éternellement est sans importance. Même chose pour forever (putStrLn "Hello"); cela ne produit pas et ne devrait pas produire un nouvel état mondial que nous pouvons consommer paresseusement.
Ben
Des langages de programmation tels que Mercury et Clean utilisant des passages explicites d’ états du monde pour fournir un modèle déclaratif d’IO sont-ils fondamentalement erronés?
Ben
@ Ben, vous parlez de comment le passage du monde fonctionne avec la concurrence? Avez-vous vu le code Rosetta pour la simultanéité de Mercury? Je me suis demandé ce que cela signifie sémantiquement aussi.
CMCDragonkai
12

Voici une réponse triviale: tout changement d'état de la monade est dû à des actions effectuées dans la monade. Si en effet l'explication «WorldState -> (a, WorldState)» revendique la même propriété, WorldState étant une valeur pure que seule la monade IO change, c'est faux. Les changements d’heure, le contenu des fichiers, l’état des descripteurs, etc. peuvent changer indépendamment de ce qui se passe dans la monade IO. C'est le but de la monade IO. Le fait que GHC transmette une valeur RealWorld (ou sa valeur inférieure) en dessous est une garantie de la régularité des choses, pour autant que je sache, si cela peut (être juste quelque chose à mettre dans la valeur ST).

Christopher Done
la source
8
ce n'est pas un problème. vous pouvez modéliser l'opération de liaison en effectuant une modification de l'état du monde dérivée d'un magasin de règles fixe mais indéterminable.
sclv
1
@sclv: oui, mais cette banque de règles fixe, mais inconnaissable, est le facteur de différenciation qui rend l'IO pas la monade d'état, cette incohérence n'est pas trouvée dans la monade d'état
Jimmy Hoffa
Un argument que j'ai entendu contre l'état du WorldState est lié à la concurrence, bien que je ne me souvienne pas de l'argument exact. Mais même quand même, je suppose que WorldState pourrait aussi encoder l'avenir, alors je ne vois toujours pas vraiment le problème. Bien sûr, je suppose qu'il me manque quelque chose.
Thomas Eding
@ JimmyHoffa: Vous pouvez toutefois conserver le magasin de règles en état.
Sclv
1
@ JimmyHoffa: c'est le but de l'abstraction. De plus, pour faire suite à mon commentaire initial, Clean modélise IO comme un monde qui passe explicitement et joyeusement dans le monde, en utilisant des types d’unicité pour éviter de tricher et de dupliquer le monde. C'est une façon de faire respecter l'abstraction.
Sclv
12

J'ai écrit un article de blog sur le sujet de la modélisation de l'IO en tant que forme de coroutine asymétrique communiquant avec le système d'exécution de votre langue. (Il est vrai que c'est la troisième partie d'une série)

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

Cet article explique en partie pourquoi il est délicat de raisonner sur la sémantique du "dépassement du monde".

Edward KMETT
la source
+1 - particulièrement intéressant, car j'ai depuis longtemps prévu d'implémenter les entrées-sorties du langage que je conçois de la même manière que cela! :)
Jules
8

Voir S'attaquer à l'escouade maladroite .

La grande raison en est que les modèles d'état RealWorld de la monade d'IO ne fonctionnent pas bien avec la simultanéité. SPJ dans ce classique lisible privilégie l’utilisation d’une sémantique opérationnelle pour la comprendre.

Tactique
la source
Je crois que c'est l'article original que je cherchais, principalement la section 3.1. Si vous l'aviez postée avant d'avoir modifié la question, j'aurais accepté votre réponse, mais je pense qu'il serait plus juste d'attendre la fin pour voir toutes les idées que les autres publieront.
Petr Pudlák
5

La principale plainte des modèles d’état de RealWorld est que, comme le dit TacTics, le passage d’un monde à l’autre ne fonctionne pas nécessairement avec la simultanéité. Mais Wouter Swierstra et Thorsten Altenkirch ont montré comment raisonner la concurrence comme un effet de "passage du monde", avec une séquence fixe mais arbitraire de fils entrelacés dans leur article "La beauté de la bête: une sématique fonctionnelle pour le groupe fantaisiste": http : //www.staff.science.uu.nl/~swier004/Publications/BeautyInTheBeast.pdf

Le code correspondant à cela est sur Hackage comme IOSpec: http://hackage.haskell.org/package/IOSpec

Je pense que la thèse de Wouter va plus en détail: http://www.staff.science.uu.nl/~swier004/Publications/Thesis.pdf

sclv
la source