
Heinrich Apfelmus
In particular, the World -> (a,World) model is unsuitable even without concurrency because it cannot distinguish
loop, loop' :: IO () loop = loop loop' = putStr "c" >> loop'
I interpret the "EDSL model" to be the operational semantics presented in the tutorial paper.
Huh?! Let's translate them. 'loop' becomes: undefined But 'loop\'' becomes: \w0 -> let (w1, ()) = putStr "c" w0 in loop w1 Because this program runs forever it makes no sense to ask what its result is after the program is run, but that's evaluation semantics. Semantically they are both undefined. But execution is something separate and there is no Haskell notion for it. In particular execution is /not/ evaluation, and the program's monadic result is not related to the world state. There is nothing wrong with it being undefined. You could even have: type RealWorld = [WorldRevision] You can view execution as the transition from one state to the next, or in other words: Each time a new world value pops up, this is the current world's state. Old revisions of the world may be kept, because of late garbage collection, but only the most recent revision is the current state of the world. If you take RealWorld to be a list (at which point the two loops above /may/ be semantically different), then it's something like a movie of world revisions. The only thing which this model really cannot capture is that of premature exit of the program. However, you can change it to: type IO = ContT RealWorld (State RealWorld) which would even invalidate the above statement that the two loops can't be distinguished. At that point it would even capture exceptions. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/