[Haskell-cafe] Referential Transparency and Monads

Brandon S. Allbery KF8NH allbery at ece.cmu.edu
Thu Apr 9 22:47:46 EDT 2009

On 2009 Apr 9, at 22:30, Jonathan Cast wrote:
> On Thu, 2009-04-09 at 21:57 -0400, Brandon S. Allbery KF8NH wrote:
>> On 2009 Apr 9, at 16:09, Luke Palmer wrote:
>>> On Thu, Apr 9, 2009 at 1:33 PM, Miguel Mitrofanov
>>> <miguelimo38 at yandex.ru> wrote:
>>>                I'm not sure what you mean by that, but semantically
>>>                IO is definitely
>>>                *not* a state monad.  Under any circumstances or any
>>>                set of assumptions.
>>>        Ehm? Why not?
>>> Mainly forkIO.  There may be other reasons.
>> I thought I had excluded that stuff to simplify the question; the  
>> fact
>> that IO is Haskell's toxic waste dump is more or less irrelevant to
>> the core concept.
> Well, the `core concept' of IO includes the concept of a user who's
> watching and interacting with your program as it runs, no?

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.

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 --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 195 bytes
Desc: This is a digitally signed message part
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090409/bc27311a/PGP.bin

More information about the Haskell-Cafe mailing list