Brandon S Allbery KF8NH wrote:
I am confused by this discussion.  I originally thought some time back that
IO was about "world passing", but in fact it's just handing off a baton to
insure that a particular sequence of IO functions is executed in the
specified sequence and not reordered.  Nothing in the "baton" is intended to
represent the actual "state of the world", nor is anything said about
concurrent actions either in another thread of the current program or
elsewhere outside the program; only ordering of calls in the *current*
thread of execution.

That explains how the IO monad forces side-effecting functions into a specified sequence, but this discussion is about how to understand what these side-effecting functions do in a *pure* framework. So the idea is to regard, for example, putStr as a pure function from a world state to a different world state, assuming that the world state contains a String which represents the contents of the terminal. We could then implement and understand putStr in pure Haskell:

  data World = World {
    terminal :: String
    ...
  }

  type IO a = World -> (World, a)

  putStr :: String -> World -> (World, ())
  putStr str world = (world {terminal = terminal world ++ str}, ())

The benefit of this point of view is that we can analyze the behavior of putStr. For example, by equational reasoning, we could derive the following equation:

  putStr s1 >> putStr s2   ==   putStr (s1 ++ s2)

It seems that we can account for more features of IO by adding more fields to the World record. This discussion is about whether we can account for *all* of IO this way.

  Tillmann
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to