[Agda] IO, semi-closed handles, and problems with extensional equality

Alan Jeffrey ajeffrey at bell-labs.com
Tue Oct 5 23:56:11 CEST 2010


OK, first pass on the bedtime reading done.

There's a lot of similarity between iteratees and Anton's resumption 
model.  Ignoring a lot of gorey details for the moment, the basic type 
of an iteree with return type A and alphabet X is:

   M = A + (X -> M)

which is isomorphic to:

   M = A + (1 x (X -> M))

i.e. a resumption model with trivial output type.

Moreover, there's an obvious extension of DFAs to handle a case of 
output, in pseudo-Agda:

   record DFA-with-output (X A : Set) : Set1 where
     field Q : Set
     field q0 : Q
     field A : (Pred Q)
     field accept : (q : Q) -> (Dec (q \in A))
     field next : (q : Q) -> (q \nin A) -> X -> Q

And (not that I've checked the details, but...) there should be mappings 
back and forth between resumptions and DFAs-with-output.

Iterees then build on this to give a parser-combinator-on-steroids 
library.  There are things which are much nicer in this model, for 
example consider a simple wc application, which with Lazy IO would be:

   main =
     getContents >> \ x ->
     putStr ("length: " ++ length x ++ ", words: " ++ length (words x))

This program is very nice, but has a horrible space leak caused by 
copying x, which (AFAICT) is tricky to fix within the lazy IO model 
without resorting to sparks, callcc, unsafePerformIO or some such.

The iteree model is driven by the data producer, so the equivalent of 
the above runs in constant space, at the cost of requiring length and 
words to be written in the iteree monad.

There are, however, examples where I don't see how to program them in 
the iteree model, for example:

   main =
     getContents >>= \x
     let xml = parseXML x in
     let xml' = transformXML xml in
     putStr (serializeXML xml')

Imagining that transformXML implements a tree automaton, this should run 
in space proportional to the height of the tree.  I'm not sure I see how 
to implement this as an iteree (without rewriting transformXML, e.g. 
differentiate the type of XML documents, and use a Huet zipper, or 
resorting to callcc).

So I can certainly see that an iteree / resumption / parser combinator 
model is necessary, but I'm not sure that everything should be forced 
into its mold.  I'm still quite tempted to explore a transactional IO model.

A.

On 10/04/2010 04:57 PM, Jeffrey, Alan S A (Alan) wrote:
> Thanks for the pointer!  More bedtime reading for me...
>
> A.
>
> On 10/04/2010 03:25 PM, Nils Anders Danielsson wrote:
>> On 2010-09-24 04:07, Alan Jeffrey wrote:
>>> If I can get this up and running, then adding a little bit of dependency
>>> to ensure that IO is being used safely should be quite routine. Hooray,
>>> Agda IO which is comparable in space usage to Haskell IO, but has the
>>> same semantics as strict IO.
>>
>> Some Haskellers which dislike lazy IO seem to be quite keen on
>> "iteratees". I don't know too much about them, but you may want to have
>> a look:
>>
>>      http://okmij.org/ftp/Streams.html
>>      http://www.google.co.uk/search?q=iteratees
>>
>> --
>> /NAD
>



More information about the Agda mailing list