Crítica da mônada de IO sendo vista como uma mônada estadual operando no mundo


46

A IOmônada em Haskell é frequentemente explicada como uma mônada estadual, onde o estado é o mundo. Portanto, um valor do tipo IO amonad é visto como algo parecido worldState -> (a, worldState).

Algum tempo atrás, li um artigo (ou um post na lista de emails / blogs) que criticou essa visão e deu várias razões pelas quais ela não está correta. Mas não me lembro nem do artigo nem das razões. Alguém sabe?

Edit: O artigo parece perdido, então vamos começar a reunir vários argumentos aqui. Estou começando uma recompensa para tornar as coisas mais interessantes.

Edit: O artigo que eu estava procurando é Abordar o esquadrão estranho: entrada / saída monádica, simultaneidade, exceções e chamadas em idioma estrangeiro em Haskell por Simon Peyton Jones. (Graças à resposta do TacTics.)



@JoachimSauer Obrigado, também é um artigo interessante, mas não é o que eu estou procurando. Essa foi focada no paradigma do estado do mundo.
Petr Pudlák 20/08/2012

Em cima da minha cabeça, os comentários aqui são um bom começo
Adam

1
O que "mundo" significa neste contexto? Presumo que não significa "A Terra". É algum tipo de escopo global? O autor que escreveu isso está se vendendo a descoberto. Se ele quer confundir e esmagar simultaneamente os egos de seus leitores, deve chamá-lo de "O Estado é o Universo" ou "O Estado de Deus". Mundo. Pah! Vocês jovens não aspiram alto o suficiente hoje em dia!
GlenPeterson

Respostas:


33

O problema IO a = worldState -> (a, worldState)é que, se isso fosse verdade, poderíamos provar isso forever (putStrLn "Hello") :: IO ae sermos undefined :: IO aiguais. Aqui está a prova cortesia de 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))

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

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

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

Em particular forever (putStrLn "Hello") = ⊥e, portanto, forever (putStrLn "Hello")e undefinedsão programas equivalentes. No entanto, claramente eles não devem ser considerados programas equivalentes, na teoria ou na prática.

Observe que esse modelo está errado, mesmo sem chamar a simultaneidade.


7
Alguém está surpreso que um programa não-determinante seja equivalente à undefinedpura semântica de Haskell? Ditos diferentes devem ser indistinguíveis na semântica pura de Haskell! Mas quando pensamos operacionalmente em nossos programas, também queremos distinguir diferentes tipos de even, mesmo quando IOnão estão envolvidos; Eu me importo se meu programa está lançando uma exceção ou inserindo um loop infinito, mesmo que você possa provar que esses são iguais, provando que ambos são ⊥. Isso não é realmente uma contradição.
Ben

3
As denotações de ⊥ e [0,1 ..] são distintas, embora sejam "não terminantes". A diferença é que denotes é denota cálculos não terminativos e não produtivos, enquanto [0,1 ..] é não terminativo, mas produtivo. Esperamos que (para sempre (putStrLn "Hello")) tenha uma denotação similar, sem finalização, mas produtiva.
Russell O'Connor

1
Mas forever (putStrLn "Hello")não é assim [0,1..], com certeza. Sua prova não é específica e worldState, portanto, também se aplica à mônada normal do estado. Assim forever (someModificationWith "Hello")também é denotacionalmente equivalente a ⊥. Estou completamente surpreso com esse resultado; não é produtivo na semântica denotacional, e o que o computador está fazendo operacionalmente enquanto esperamos para sempre é irrelevante. A mesma coisa para forever (putStrLn "Hello"); não produz e não deve produzir um novo estado mundial que possamos de alguma forma consumir preguiçosamente.
Ben

As linguagens de programação como Mercury e Clean que usam passagem explícita de estado mundial para fornecer um modelo declarativo de E / S estão fundamentalmente erradas?
Ben

@Ben, você está se referindo a como a passagem do mundo funciona com simultaneidade? Você viu o código da roseta para a simultaneidade de Mercúrio? Eu me perguntei o que isso significa semanticamente também.
CMCDragonkai

12

Aqui está uma resposta trivial: qualquer alteração no estado da mônada do estado deve-se a qualquer ação executada na mônada. Se, de fato, a explicação “WorldState -> (a, WorldState)” reivindica a mesma propriedade, com o WorldState sendo um valor puro que somente a mônada de IO muda, está errado. As mudanças de horário, o conteúdo dos arquivos, o estado dos manipuladores etc. podem mudar independentemente do que acontece na mônada de E / S. Esse é o ponto da mônada de IO. O fato de o GHC transmitir um valor do RealWorld (ou onde estava) abaixo é garantir que as coisas sejam executadas em ordem, tanto quanto eu sei, se isso (pode ser apenas algo para colocar no valor ST).


8
isso não é realmente um problema. você pode modelar a operação de ligação como executando uma modificação no estado mundial derivada de algum armazenamento de regras fixo, mas incognoscível.
SCLV

1
@sclv: sim, mas esta loja regra fixa-mas-incognoscível é o fator de diferenciação que faz com que o IO não a Mônada estado, esta inconsistência não é encontrado na mônada estado
Jimmy Hoffa

Um argumento que ouvi contra o estado WorldState está relacionado à simultaneidade, embora não me lembre do argumento exato. Mesmo assim, eu suponho que o WorldState possa codificar o futuro para ele também, então ainda não vejo o problema. Claro, suponho que estou perdendo alguma coisa.
Thomas Eding

@ JimmyHoffa: Você pode carregar o armazenamento de regras no estado.
Sclv 04/04/12

1
@ JimmyHoffa: esse é o objetivo da abstração. Além disso, para acompanhar meu comentário inicial, o Clean modela a IO como uma passagem pelo mundo de maneira explícita e feliz, usando tipos de exclusividade para garantir que você não trapaceie e "duplique" o mundo. Essa é uma maneira de impor a abstração.
Sclv 5/09/12

12

Eu escrevi uma postagem no blog sobre o tópico de como modelar IO como uma forma de corotina assimétrica se comunicando com o sistema de tempo de execução para o seu idioma. (É reconhecidamente a terceira parte de uma série)

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

Esse post aborda um pouco do porquê de ser estranho argumentar sobre a semântica da 'passagem pelo mundo'.


+1 - especialmente interessante, pois há muito planejo implementar o IO da linguagem que estou projetando de maneira semelhante a isso! :)
Jules

8

Veja Lidando com o esquadrão estranho .

A grande razão é que os modelos de estado da Mônada IO do RealWorld não funcionam bem com simultaneidade. O SPJ neste clássico legível favorece o uso de uma semântica operacional para entendê-lo.


Eu acredito que este é o artigo original que eu estava procurando, principalmente a seção 3.1. Se você o tivesse postado antes de eu editar a pergunta, eu teria aceitado sua resposta, mas agora acho mais justo esperar até o final, para ver todas as idéias que outras pessoas postarão.
Petr Pudlák

5

A principal reclamação sobre os modelos de estado do RealWorld é que, como o TacTics diz, a passagem pelo mundo não funciona necessariamente com simultaneidade. Mas Wouter Swierstra e Thorsten Altenkirch mostraram como argumentar sobre a simultaneidade como efeito de "passagem pelo mundo", com uma sequência fixa, mas arbitrária, de tópicos intercalados em seu artigo "A Bela na fera: uma semântica funcional para o esquadrão estranho": http : //www.staff.science.uu.nl/~swier004/Publications/BeautyInTheBeast.pdf

O código correspondente a isso está no Hackage como IOSpec: http://hackage.haskell.org/package/IOSpec

Eu acho que a tese de Wouter entra em mais detalhes: http://www.staff.science.uu.nl/~swier004/Publications/Thesis.pdf

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.