[Haskell] Re: [Haskell-cafe] SimonPJ and Tim Harris explain STM - video

Liyang HU haskell.org at liyang.hu
Thu Nov 23 17:42:57 EST 2006


On 23/11/06, Benjamin Franksen <benjamin.franksen at bessy.de> wrote:
> One answer is in fact "to make it so that Console.Write can be rolled back
> too". To achieve this one can factor the actual output to another task and
> inside the transaction merely send the message to a transactional channel
> (TChan):

So, you could simply return the console output as (part of) the result
of the atomic action. Wrap it in a WriterT monad transformer, even.

   (one, console) <- atomic $ runWriterT $ do
       tell "hello world\n"
       return 1
   putStr console

(Not terribly efficient, but you get the idea.)

You're just calculating what output to make inside the transaction;
the actual outputting happens outside, once the transaction commits.

> Another task regularly takes messages from the channel

With STM, the outputter task won't see any messages from the channel
until your main atomic block completes, after which you're living in
IO-land, so you might as well do the output yourself.

Pugs/Perl 6 takes the approach that any IO inside an atomic block
raises an exception.

> Unfortunately I can't see how to generalize this to input as well...

The dual of how you described the output situation: read a block of
input before the transaction starts, and consume this during the
transaction. I guess you're not seeing how this generalises because
potentially you won't know how much of the input you will need to read
beforehand... (so read all available input?(!) You have the dual
situation in the output case, in that you can't be sure how much
output it may generate / you will need to buffer.)

   input <- hGetContent file
   atomic $ flip runReaderT input $ do
       input <- ask
       -- do something with input
       return 42

(This is actually a bad example, since hGetContents reads the file
lazily with interleaved IO...)


More information about the Haskell-Cafe mailing list