A IO
mônada em Haskell é frequentemente explicada como uma mônada estadual, onde o estado é o mundo. Portanto, um valor do tipo IO a
monad é 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.)
fonte
Respostas:
O problema
IO a = worldState -> (a, worldState)
é que, se isso fosse verdade, poderíamos provar issoforever (putStrLn "Hello") :: IO a
e sermosundefined :: IO a
iguais. Aqui está a prova cortesia de dolio (2010, irc):Lema:
(\r w -> r (snd $ m w)) ⊥ = ⊥
Portanto
forever m = fix (\r -> \w -> r (snd $ m w)) = ⊥
Em particular
forever (putStrLn "Hello") = ⊥
e, portanto,forever (putStrLn "Hello")
eundefined
sã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.
fonte
undefined
pura 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 quandoIO
nã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.forever (putStrLn "Hello")
não é assim[0,1..]
, com certeza. Sua prova não é específica eworldState
, portanto, também se aplica à mônada normal do estado. Assimforever (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 paraforever (putStrLn "Hello")
; não produz e não deve produzir um novo estado mundial que possamos de alguma forma consumir preguiçosamente.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).
fonte
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'.
fonte
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.
fonte
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
fonte