[Haskell-cafe] Referential Transparency and Monads

Luke Palmer lrpalmer at gmail.com
Fri Apr 10 00:14:15 EDT 2009

On Thu, Apr 9, 2009 at 8:47 PM, Brandon S. Allbery KF8NH <
allbery at ece.cmu.edu> wrote:

> Yes.  That's the opaque "real world";  an I/O operation conceptually
> modifies this state, which is how things get tied together.  Ordinary user
> programs can't interact with the "real world" sate except via functions
> defined on IO, which are assumed to modify the state; that's exactly how
> non-RT actions are modeled via RT code.
> Stuff like forkIO and newIORef can also be understood that way, it's just a
> bit more complex to follow them around.

newIORef is trivial: just keep a unique counter in the state.

Have you tried forkIO?  I used to think that "world passing" was an
acceptable, if ugly, semantics for IO.  However, after doing some formal
modeling, I realized that forkIO breaks the model altogether.  What happens
to the end state of the forked thread?

If it really is thought of that way, surely you will be able to create a
pure IO simulator as a state monad (for an arbitrarily complex world) that
handles only forkIO, threadDelay, and print  (just using a write buffer).
 Think about that for a second.


> Please note that ghc *does* implement IO (from Core up, at least) this way,
> modulo unboxed tuples, so claims that it is "wrong" are dubious at best.
>>    s <- readFile "/my_file"
>>    writeFile "/my_file" "Hello, world!\n"
>>    threadDelay 10000 -- If you don't like threadDelay, just substitute
>> forcing
>>                      -- an expensive thunk here
>>    writeFile "/my_file" s
>> As a function from initial state to final state, this program is just
>> the identity; but surely this program should be considered different
> It is?
> > -- these implicitly are considered to return a modified RealWorld
> > readFile :: RealWorld -> (String,RealWorld)
> > writeFile :: RealWorld -> ((),RealWorld)
> > threadDelay :: RealWorld -> ((),RealWorld)
> >
> > main :: RealWorld -> ((),RealWorld)
> > main state =
> >   case readFile state "/my_file" of
> >     (s,state') ->
> >        case writeFile state' "/my_file" "Hello, world!\n" of
> >          (_,state'') ->
> >             case threadDelay state'' 10000 of
> >               (_,state'') -> writeFile "/my_file" s
> This is just the State monad, unwrapped.  And the differences between this
> and the actual GHC implementation are the use of unboxed tuples and
> RealWorld actually being a type that can't be accessed by normal Haskell
> code.
> --
> brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery at kf8nh.com
> system administrator [openafs,heimdal,too many hats] allbery at ece.cmu.edu
> electrical and computer engineering, carnegie mellon university    KF8NH
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090409/2a72bc04/attachment-0001.htm

More information about the Haskell-Cafe mailing list