IO-System

Glynn Clements glynn.clements@virgin.net
Tue, 17 Sep 2002 02:37:28 +0100


David Sabel wrote:

> > The runtime system mostly has no concept of IO vs. non-IO evaluation.
> > The IO monad is implemented as the following type:
> >
> >   newtype IO a = IO (State# RealWorld ->
> >    (# State# RealWorld, a #)
> >
> > which means that an IO action is simply a function from the world state
> > to a pair of a new world state and a value.  In other words, it's a
> > straightfoward state monad, except that we use some optimised
> > representations to eliminate some of the overhead of passing the state
> > around.
> >
> > Cheers,
> > Simon
> 
> Ok so far, but when is the IO action performed?
> 
> Look at this small programm:
> 
>     module Main(main) where
> 
>     main = echoTwice
> 
>     echo = getChar >>= putChar
> 
>     echoTwice = echo >> echo
> 
> while executing: the program reads first two chararcters and then it writes
> the characters, but
> in my opinion it would be right to read one character, then write one
> characater, then read, then write.
> What's the reason for it?

Buffering.

If stdin/stdout correspond to a terminal, they are initially
line-buffered; otherwise, they are initially fully (block) buffered. 
Also, if you're reading from a terminal, the terminal driver might
perform line buffering also (although, AFAICT, the run-time explicitly
turns it off).

You can change the buffering of stdin/stdout using IO.hSetBuffering. 
The terminal buffering can be controlled using
PosixTTY.setTerminalAttributes.

BTW, this isn't a Haskell issue; you would see the same behaviour from
a program written in C.

-- 
Glynn Clements <glynn.clements@virgin.net>